ukui-biometric-auth/0000755000175000017500000000000014101720251013356 5ustar fengfengukui-biometric-auth/CMakeLists.txt0000644000175000017500000000177514101710120016122 0ustar fengfengcmake_minimum_required(VERSION 2.6) project(ukui-biometric-auth) find_package(Qt5 COMPONENTS Core Widgets DBus) find_package(Qt5LinguistTools) find_package(OpenCV REQUIRED) find_package(PkgConfig) pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) set(UKUI_BIOMETRIC_DIR /usr/share/ukui-biometric) set(CMAKE_INSTALL_PREFIX /usr) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror") set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 11) set (CONDOR_SCRIPT_PERMS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) add_compile_options(-fPIC) add_definitions(-DUKUI_BIOMETRIC=${UKUI_BIOMETRIC_DIR}) add_definitions(-DCONFIG_FILE=/etc/biometric-auth/ukui-biometric.conf) add_subdirectory(bioauth) add_subdirectory(bioauth-bin) add_subdirectory(pam-biometric) add_subdirectory(polkit-agent) add_subdirectory(images) add_dependencies(bioauth BioAuth) add_dependencies(polkit-ukui-authentication-agent-1 BioAuthWidgets) ukui-biometric-auth/man/0000755000175000017500000000000014064326115014142 5ustar fengfengukui-biometric-auth/man/biodrvctl.10000644000175000017500000000120214064326115016207 0ustar fengfeng.\" Man Page for bioctl .TH BIOCTL 1 "August 05, 2018" .SH "NAME" bioctl \- control tool for biometric device driver .SH "SYNOPSIS" .B biodrvctl .SH "DESCRIPTION" .B biodrvctl is a control tool for biometric device driver in the UKUI desktop. It changes the status of biometric device driver. .TP \fB enable\fR Enable biometric device driver. .TP \fB disable\fR Disable biometric device driver. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: http://github.com/ukui/ukui-biometric-auth/issues .SH "AUTHORS" .SS This Manual Page has been written for the UKUI Desktop Environment by: yanghao (2018) ukui-biometric-auth/man/bioctl.10000644000175000017500000000133214064326115015477 0ustar fengfeng.\" Man Page for bioctl .TH BIOCTL 1 "August 05, 2018" .SH "NAME" bioctl \- control tool for biometric authentication .SH "SYNOPSIS" .B bioctl .SH "DESCRIPTION" .B bioctl is a control tool for biometric authentication in the UKUI desktop. It show or change the status that biometric authentication is enabled or not. .TP \fB status\fR Show the status of biometric authentication. .TP \fB enable\fR Enable biometric authentication. .TP \fB disable\fR Disable biometric authenticaion. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: http://github.com/ukui/ukui-biometric-auth/issues .SH "AUTHORS" .SS This Manual Page has been written for the UKUI Desktop Environment by: yanghao (2018) ukui-biometric-auth/man/bioauth.10000644000175000017500000000121414064326115015655 0ustar fengfeng.\" Man Page for bioauth .TH BIOCTL 1 "August 05, 2018" .SH "NAME" bioauth \- command line binary for biometric authentication .SH "SYNOPSIS" .B bioauth .SH "DESCRIPTION" .B bioauth is a command line tool for biometric authentication in the UKUI desktop. It authenticate user by verify biometric features. .TP \fB --user\fR The user to be anthenticated. .TP \fB --device\fR The device for authentication. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: http://github.com/ukui/ukui-biometric-auth/issues .SH "AUTHORS" .SS This Manual Page has been written for the UKUI Desktop Environment by: yanghao (2018) ukui-biometric-auth/COPYING0000644000175000017500000010451314064326115014426 0ustar fengfeng GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ukui-biometric-auth/pam-biometric/0000755000175000017500000000000014107167520016120 5ustar fengfengukui-biometric-auth/pam-biometric/pam_biometric.c0000644000175000017500000003762314107167520021111 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #define PAM_SM_AUTH #include "generic.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /* Declare log function */ extern int enable_debug; extern char *log_prefix; extern int logger(char *format, ...); static int ukui_biometric_lock = 0; int enable_biometric_authentication(pam_handle_t *pamh); /* GUI child process alive status */ static int child_alive = 1; /* Signal handler */ static void signal_handler(int signo) { if (signo == SIGUSR1) child_alive = 0; /* GUI child process has terminated */ logger("signal_handler is triggered\n"); } /* * Check if the service should use biometric authentication */ int service_filter(char *service) { if (strcmp(service, "lightdm") == 0) { int ret = system("/bin/chmod -f a+wr /tmp/bio.log"); (void)ret; /* Suppress gcc ignoring return value warning */ return 1; } if (strcmp(service, "ukui-screensaver-qt") == 0) return 1; if (strcmp(service, "sudo") == 0) return 1; if (strcmp(service, "login") == 0) return 1; if (strcmp(service, "su") == 0) return 1; // if (strcmp(service, "mate-screensaver") == 0) // return 1; if (strcmp(service, "polkit-1") == 0) return 1; #ifdef ENABLE_BIOTEST if (strcmp(service, "biotest") == 0) return 1; #endif return 0; } /* * Invoke the PAM conversation function */ int call_conversation(pam_handle_t *pamh, int msg_style, char *msg, char *resp) { /* PAM data structures used by conversation */ const struct pam_message *message[1] = {0}; struct pam_message *message_tmp = 0; struct pam_response *response = 0; const struct pam_conv *conv_struct = 0; int status = -1; status = pam_get_item(pamh, PAM_CONV, (const void **)&conv_struct); if (status != PAM_SUCCESS) return PAM_SYSTEM_ERR; message_tmp = (struct pam_message *)malloc(sizeof(struct pam_message)); message_tmp->msg_style = msg_style; message_tmp->msg = msg; message[0] = message_tmp; logger("Call conv callback function\n"); status = conv_struct->conv(1, message, &response, conv_struct->appdata_ptr); logger("Finish conv callback function\n"); if (resp) strcpy(resp, response->resp); /* Use typecast to suppress gcc warnings */ free((void *)message[0]); if (response) free(response->resp); free(response); return status; } /* GUI child process */ void child(char *service, char *username, char *xdisp) { char *gui = "/usr/bin/bioauth"; logger("Child process will be replaced.\n"); int fd = open("/dev/null", O_WRONLY); dup2(fd, 2); execl(gui, "bioauth", "--service", service, "--user", username, // "--display", xdisp, enable_debug ? "--debug" : "", (char *)0); /* * execl almost always succeed as long as the GUI executable file exists. * Though invoking GUI under console will exit with error, the GUI child * process won't reach here. Therefore, the following code won't be * executed in general. */ logger("Fatal error: execl(gui) failed in child process. " "This is an extremely rare condition. Please ensure that the " "biometric-authentication executable file exists.\n"); logger("Use password as a fallback\n"); logger("Child _exit with BIO_IGNORE\n"); /* Child process exits */ _exit(BIO_IGNORE); } void handler() { return; } /* PAM parent process */ int parent(int pid, pam_handle_t *pamh, int need_call_conv) { logger("Parent process continue running.\n"); int child_status = -1; /* * 1. If calling conversation function is not needed, wait the child * until it exits. * 2. Otherwise, send a text info to application at first and then * call the conversation function to request the password. The returned * password is unused. * Note: During requesting the password, screensaver won't display the * prompting message, while greeter will display it into the password * entry. If there is a "\n" at the end of the message, it will be * displayed on the Label above the password entry. */ if (need_call_conv) { char *lang = getenv("LANG"); char *msg1, *msg2; if (lang && !strncmp(lang, "zh_CN", 5)) msg1 = "请进行生物识别或点击“切换到密码登录”\n"; else msg1 = "Use biometric authentication or click " "\"Switch to password\"\n"; #ifdef EMPTY_PAM_PWD_PROMPT msg2 = ""; #else msg2 = "pam_biometric.so needs a fake ENTER:"; #endif if (signal(SIGUSR1, signal_handler) == SIG_ERR) logger("Fatal Error. Can't catch SIGUSR1\n"); reinvoke: call_conversation(pamh, PAM_TEXT_INFO, msg1, NULL); call_conversation(pamh, PAM_PROMPT_ECHO_OFF, msg2, NULL); /* GUI child process is still alive. This enter is typed by user. */ if (child_alive == 1) goto reinvoke; signal(SIGUSR1, SIG_DFL); waitpid(pid, &child_status, 0); } else { logger("Waiting for the GUI child process to exit...\n"); //由于sudo命令在进入pam认证时,会阻塞来自终端的SIGINT以及SIGQUIT信号,导致使用 //pam认证时,按下Ctrl+C无反应,认证完成后,sudo会退出,这里为了简单,取消了阻塞 //信号,捕获信号但不做处理,在认证完成后,恢复原本阻塞状态 sigset_t mask; sigprocmask(SIG_BLOCK,NULL,&mask); sigprocmask(SIG_UNBLOCK,&mask,NULL); signal(SIGINT,handler); waitpid(pid, &child_status, 0); logger("GUI child process has exited.\n"); sigprocmask(SIG_SETMASK,&mask,NULL); } /* * Determine the return value of PAM according to the return value of * child process. */ int bio_result = BIO_ERROR; /* biometric result code */ if (WIFEXITED(child_status)) bio_result = WEXITSTATUS(child_status); else /* This may be because the GUI child process is invoked under console. */ logger("The GUI-Child process terminate abnormally.\n"); if (bio_result == BIO_SUCCESS) { if(!enable_biometric_authentication(pamh)) { logger("disable biometric authentication.\n"); return PAM_SYSTEM_ERR; } logger("pam_biometric.so return PAM_SUCCESS\n"); return PAM_SUCCESS; } else if (bio_result == BIO_IGNORE) { /* Override msg1 to empty the label. We are ready to enter the password module. */ call_conversation(pamh, PAM_TEXT_INFO, "", NULL); ukui_biometric_lock = 1; logger("pam_biometric.so return PAM_IGNORE\n"); return PAM_IGNORE; } else { logger("pam_biometric.so return PAM_SYSTEM_ERR\n"); ukui_biometric_lock = 1; return PAM_SYSTEM_ERR; } } /* Set environment variables related to displaying */ void check_and_set_env(pam_handle_t *pamh, char **xdisp, char **xauth) { *xdisp=getenv("DISPLAY"); *xauth=getenv("XAUTHORITY"); if (*xdisp == 0){ pam_get_item(pamh, PAM_XDISPLAY, (const void **)xdisp); if (*xdisp) setenv("DISPLAY",*xdisp,-1); } if (*xauth == 0) setenv("XAUTHORITY", "/var/run/lightdm/root/:0", -1); *xdisp=getenv("DISPLAY"); *xauth=getenv("XAUTHORITY"); if (*xdisp == 0) logger("Warning: DISPLAY env is still empty, " "this is not an error if you are using terminal\n"); if (*xauth == 0) logger("Warning: XAUTHORITY env is still empty, " "this is not an error if you are using terminal\n"); } /* Biometric processing function for generic purpose */ int biometric_auth_independent(pam_handle_t *pamh , char *service, int need_call_conv) { /* Get the username */ char *username = 0; pam_get_item(pamh, PAM_USER, (const void **)&username); /* Check and set environment variables */ char *xdisp, *xauth; check_and_set_env(pamh, &xdisp, &xauth); /* Detach child process */ unsigned int pid; pid = fork(); if (pid == 0 ) { child(service, username, xdisp); logger("Should never reach here.\n"); return PAM_SYSTEM_ERR; } else if (pid > 0) { return parent(pid, pamh, need_call_conv); } else { logger("Fork Error!\n"); return PAM_SYSTEM_ERR; } } /* Biometric processing function fot polkit-1 */ int biometric_auth_polkit() { logger("Current service is polkit-1\n"); const char *fifo_name = "/tmp/bio.fifo"; if(access(fifo_name, F_OK) == -1) { int res = mkfifo(fifo_name, 0777); if(res != 0) { logger("Can't create FIFO file\n"); return PAM_SYSTEM_ERR; } } int fifo_rd = open(fifo_name, O_RDONLY); if (fifo_rd == -1) return PAM_SYSTEM_ERR; logger("Before reading FIFO\n"); char buffer[8] = {0}; if(read(fifo_rd, buffer, 8) == -1) return PAM_SYSTEM_ERR; logger("After reading FIFO\n"); int result_code; sscanf(buffer, "%d", &result_code); remove(fifo_name); if (result_code == BIO_SUCCESS) { logger("pam_biometric.so return PAM_SUCCESS\n"); return PAM_SUCCESS; } else if (result_code == BIO_IGNORE) { logger("pam_biometric.so return PAM_IGNORE\n"); return PAM_IGNORE; } else { logger("pam_biometric.so return PAM_SYSTEM_ERR\n"); return PAM_SYSTEM_ERR; } } int biometric_auth_embeded(pam_handle_t *pamh) { /* * By convention, PAM module sends a string "BIOMETRIC_PAM" to * lightdm and this message will be forwarded to greeter. After * the authentication is completed, greeter will send a string * "BIOMETRIC_IGNORE"/"BIOMETRIC_SUCCESS" to lightdm and then it * will be forwarded to PAM module. We can get the authentication * status by comparing strings. */ char resp[96] = {0}; if(enable_biometric_auth_double()) call_conversation(pamh, PAM_PROMPT_ECHO_OFF, BIOMETRIC_PAM_DOUBLE, resp); else call_conversation(pamh, PAM_PROMPT_ECHO_OFF, BIOMETRIC_PAM, resp); if (strcmp(resp, BIOMETRIC_IGNORE) == 0) return PAM_IGNORE; else if (strcmp(resp, BIOMETRIC_SUCCESS) == 0){ if(!enable_biometric_authentication(pamh)) { logger("disable biometric authentication.\n"); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } else if (strcmp(resp, BIOMETRIC_FAILED) == 0) return PAM_AUTH_ERR; else return PAM_SYSTEM_ERR; } void get_greeter_session(char buf[], int len) { FILE *stream; char cmd[] = "ps -aux | grep greeter-session | grep -v grep | awk '{print $13}' | awk -F '/' '{print $4}'"; memset(buf, 0, len); stream = popen(cmd, "r"); if(fgets(buf, len, stream) == NULL) logger("get greeter session error: %d\n", errno); buf[strlen(buf)-1] = '\0'; if(strlen(buf) == 0) { char cmd1[] = "ps aux | grep ukui-greeter | grep -v grep | wc -l"; pclose(stream); stream = popen(cmd1, "r"); if(fgets(buf, len, stream) == NULL) logger("get greeter session error: %d\n", errno); int i = atoi(buf); if(i > 0) strcpy(buf, "ukui-greeter"); } pclose(stream); } int enable_by_polkit() { FILE *file; char buf[1024]; if( (file = fopen(BIO_COM_FILE, "r")) == NULL) { logger("open communication file failed: %s\n", strerror(errno)); return 0; } memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), file); fclose(file); if(remove(BIO_COM_FILE) < 0) logger("remove communication file failed: %s\n", strerror(errno)); logger("%s\n", buf); if(strcmp(buf, "polkit-ukui-authentication-agent-1") == 0) return 1; return 0; } int enable_biometric_authentication(pam_handle_t *pamh) { char conf_file[] = GET_STR(CONFIG_FILE); FILE *file; char line[1024], is_enable[16]; int i; if((file = fopen(conf_file, "r")) == NULL){ logger("open configure file failed: %s\n", strerror(errno)); return 0; } while(fgets(line, sizeof(line), file)) { i = sscanf(line, "EnableAuth=%s\n", is_enable); if(i > 0) { logger("EnableAuth=%s\n", is_enable); break; } } fclose(file); if(!strcmp(is_enable, "true")) return 1; return 0; } int enable_biometric_auth_double() { char conf_file[] = GET_STR(CONFIG_FILE); FILE *file; char line[1024], is_enable[16]; int i; if((file = fopen(conf_file, "r")) == NULL){ logger("open configure file failed: %s\n", strerror(errno)); return 0; } while(fgets(line, sizeof(line), file)) { i = sscanf(line, "DoubleAuth=%s\n", is_enable); if(i > 0) { logger("DoubleAuth=%s\n", is_enable); break; } } fclose(file); if(!strcmp(is_enable, "true")) return 1; return 0; } /* * SPI interface */ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { for(int i = 0; i < argc; i++) { if(strcmp(argv[i], "debug") == 0) { enable_debug = 1; log_prefix = "PAM_BIO"; } } logger("Invoke libpam_biometric.so module\n"); char *service = 0; if(!enable_biometric_authentication(pamh) || ukui_biometric_lock) { logger("disable biometric authentication.\n"); return PAM_IGNORE; } logger("enable biometric authentication.\n"); pam_get_item(pamh, PAM_SERVICE, (const void **)&service); /* Service filter */ if (!service_filter(service)){ logger("Service <%s> should not use biometric-authentication\n", service); return PAM_IGNORE; } /* Different services use different processing function */ if (strcmp(service, "lightdm") == 0) { char buf[128]; get_greeter_session(buf, sizeof(buf)); logger("current greeter: %s\n", buf); if(strcmp(buf, "ukui-greeter") == 0 || strcmp(buf, "ukui-greeter-wayland") == 0) return biometric_auth_embeded(pamh); // else // return biometric_auth_independent(pamh, "lightdm", 1); } else if (strcmp(service, "ukui-screensaver-qt")==0) return biometric_auth_embeded(pamh); else if (strcmp(service, "polkit-1") == 0){ if(enable_by_polkit()) return biometric_auth_embeded(pamh); else logger("[PAM_BIOMETRIC]: It's not polkit-ukui-authentication-agent-1.\n"); } else if (strcmp(service, "sudo") == 0) return biometric_auth_independent(pamh, "sudo", 0); else if (strcmp(service, "login") == 0) return biometric_auth_independent(pamh, "login", 0); else if (strcmp(service, "su") == 0) return biometric_auth_independent(pamh, "su", 0); // else if (strcmp(service, "mate-screensaver") == 0) // return biometric_auth_independent(pamh, "mate-screensaver", 1); #ifdef ENABLE_BIOTEST else if (strcmp(service, "biotest") == 0) return biometric_auth_independent(pamh, "biotest", 1); #endif else logger("Service <%s> slip through the service filter\n", service); return PAM_IGNORE; } int pam_sm_setcred (pam_handle_t *pamh, int flags , int argc , const char **argv ) { return PAM_SUCCESS; } ukui-biometric-auth/pam-biometric/CMakeLists.txt0000644000175000017500000000334114064326115020660 0ustar fengfengproject(pam_biometric) find_path(PAM_INCLUDE_DIR security/pam_modules.h) find_library(PAM_LIB NAMES pam) if(NOT PAM_INCLUDE_DIR OR NOT PAM_LIB) message(FATAL_ERROR "pam_modules.h not found") endif() set(SCRIPTS_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/bin) configure_file( ${PROJECT_SOURCE_DIR}/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy ) configure_file( ${PROJECT_SOURCE_DIR}/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy ) configure_file( ${PROJECT_SOURCE_DIR}/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.biorestart.policy ) set(pam_SRCS pam_biometric.c logger.c ) include_directories( ../common ${PAM_INCLUDE_DIR} ) add_library(pam_biometric SHARED ${pam_SRCS}) target_link_libraries(pam_biometric ${PAM_LIB}) #去除lib前缀 set_target_properties(pam_biometric PROPERTIES PREFIX "") install(TARGETS pam_biometric DESTINATION /lib/security) install(FILES pam-configs/pam-biometric DESTINATION /usr/share/pam-configs) install(FILES data/ukui-biometric.conf DESTINATION /etc/biometric-auth) install(FILES ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy ${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.biorestart.policy DESTINATION /usr/share/polkit-1/actions ) install(FILES utils/bioctl utils/bioctl-helper utils/biodrvctl utils/biorestart DESTINATION bin PERMISSIONS ${CONDOR_SCRIPT_PERMS}) ukui-biometric-auth/pam-biometric/logger.c0000644000175000017500000000244114064326115017543 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include #include #include #include #include #include #include #include int enable_debug; char *log_prefix; void logger(char *format, ...) { if(!enable_debug){ return; } va_list args; time_t t = time(NULL); char timestr[32] = {0}; strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&t)); //产生"YYYYMMDD hh:mm:ss"格式的字符串。 fprintf(stderr, "[%s] %s - ", log_prefix, timestr); va_start(args, format); /* 初始化 args */ vfprintf(stderr, format, args); } ukui-biometric-auth/pam-biometric/utils/0000755000175000017500000000000014064326115017257 5ustar fengfengukui-biometric-auth/pam-biometric/utils/bioctl-helper0000755000175000017500000000306614064326115021743 0ustar fengfeng#!/bin/bash # Usage: bioctl status|enable|disable CONFIG_DIR=/etc/biometric-auth CONFIG_FILE=$CONFIG_DIR/ukui-biometric.conf function test_privilege() { if [ `whoami` != 'root' ]; then echo $(gettext "Permission denied, please run by root") exit 1; fi } if [ ! -d $CONFIG_DIR ]; then mkdir -p $CONFIG_DIR fi if [ ! -f $CONFIG_FILE ]; then touch $CONFIG_FILE fi contain_key=`grep -c "^EnableAuth=" $CONFIG_FILE` if [ "$1" = "enable" ]; then test_privilege # 生物识别管理工具在打开生物识别开关的时候会调用这个脚本, # 如果之前手动改过pam的配置文件,在执行这个脚本的时候会有交互 # 性提示,但前端程序上看不到,导致生物识别管理工具阻塞,不过 # 由于在安装pam_biomtric这个包时已经执行了这个命令,且会通过 # /etc/biometric-auth 配置文件来判断生物识别状态,所以也不需要 #执行 pam-auth-update 了。 #pam-auth-update --package pam-biometric if [ "$contain_key" = "1" ]; then sed -i 's/^EnableAuth=[a-zA-Z0-9]*/EnableAuth=true/g' $CONFIG_FILE else echo "EnableAuth=true" >> $CONFIG_FILE fi elif [ "$1" = "disable" ]; then test_privilege if [ "$contain_key" = "1" ]; then sed -i 's/^EnableAuth=[a-zA-Z0-9]*/EnableAuth=false/g' $CONFIG_FILE else echo "EnableAuth=false" >> $CONFIG_FILE fi elif [ "$1" = "status" ]; then cur_status=`sed '/^EnableAuth/!d;s/.*=//' $CONFIG_FILE` if [ "$cur_status" = "true" ]; then echo "enable" else echo "disable" fi else echo "Usage: bioctl status|enable|disable" fi exit 0 ukui-biometric-auth/pam-biometric/utils/bioctl0000755000175000017500000000047014064326115020462 0ustar fengfeng#!/bin/bash # Usage: bioctl status|enable|disable if [ "$1" = "enable" ]; then pkexec /usr/bin/bioctl-helper enable elif [ "$1" = "disable" ]; then pkexec /usr/bin/bioctl-helper disable elif [ "$1" = "status" ]; then /usr/bin/bioctl-helper status else echo "Usage: bioctl status|enable|disable" fi exit 0 ukui-biometric-auth/pam-biometric/utils/biodrvctl0000755000175000017500000000134214064326115021175 0ustar fengfeng#!/bin/bash export TEXTDOMAINDIR=/usr/share/locale export TEXTDOMAIN=biodrvctl . gettext.sh function usage() { echo -e "Usage:" echo -e " biodrvctl "$(gettext "COMMAND DRIVER-NAME") echo echo -e "Build-in command:" echo -e " enable\t"$(gettext "Enable device's driver") echo -e " disable\t"$(gettext "Disable device's driver") } if [ $# -ne 2 ]; then usage exit 1 fi if [ `whoami` != 'root' ]; then echo $(gettext "Permission denied, please run by root") exit 1 fi if [ "$1" == "enable" ]; then biometric-config-tool enable-driver $2 elif [ "$1" == "disable" ]; then biometric-config-tool disable-driver $2 else usage exit 1 fi if [ $? -eq 0 ]; then systemctl restart biometric-authentication.service fi exit $? ukui-biometric-auth/pam-biometric/utils/biorestart0000755000175000017500000000024514064326115021364 0ustar fengfeng#!/bin/bash if [ `whoami` != 'root' ]; then echo $(gettext "Permission denied, please run by root") exit 1 fi systemctl restart biometric-authentication.service ukui-biometric-auth/pam-biometric/biotest.c0000644000175000017500000000776714064326115017755 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include #include #include #include #include #define BUF_SIZE 128 #define DISABLE_ECHO 0 #define ENABLE_ECHO 1 char * getpasswd(int enable_echo); int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); struct pam_conv conv = { pam_conversation, NULL }; int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int count = num_msg; char *password = 0; *resp = (struct pam_response *)malloc(num_msg * sizeof(struct pam_response)); /*指针备份,下面的循环需要指针后移*/ struct pam_response *tmp_save = (struct pam_response *)(*resp); memset(*resp, 0, num_msg * sizeof(struct pam_response)); while(count-- >= 1){ switch((*msg)->msg_style){ case PAM_PROMPT_ECHO_OFF: printf("%s",(*msg)->msg); password = getpasswd(DISABLE_ECHO); (*resp)->resp = password; (*resp)->resp_retcode = 0; break; case PAM_PROMPT_ECHO_ON: printf("%s",(*msg)->msg); password = getpasswd(ENABLE_ECHO); (*resp)->resp = password; (*resp)->resp_retcode = 0; break; case PAM_ERROR_MSG: printf("%s",(*msg)->msg); break; case PAM_TEXT_INFO: printf("%s",(*msg)->msg); break; default: printf("Should not reach here!\n"); } if(count != 0){ msg++; (*resp)++; } } /*指针归位 方法1*/ /* unsigned long address_value = (unsigned long)(*resp) - (num_msg -1) * sizeof(struct pam_response); (*resp) = (struct pam_response *)address_value; */ /*指针归位 方法2*/ (*resp) = tmp_save; return PAM_SUCCESS; } int main(int argc, char *argv[]) { pam_handle_t *pamh = NULL; int retval; char *user = NULL; if(argc == 2){ user = argv[1]; } else { printf("Usage: You must specify a username.\n"); exit(1); } retval = pam_start("biotest", user, &conv, &pamh); if(retval == PAM_SUCCESS){ printf("PAM started Success.\n"); } else { printf("PAM started Failed.\n"); } int auth_status = pam_authenticate(pamh,0); if(auth_status != PAM_SUCCESS){ const char * error_msg = pam_strerror(pamh, auth_status); printf("Auth Status : %s\n",error_msg); } else { printf("Authenticate Success!\n"); } if(pam_end(pamh, retval) != PAM_SUCCESS){ pamh = NULL; printf("Failed to terminate PAM."); exit(1); } return (retval == PAM_SUCCESS ? 0:1); } char * getpasswd(int enable_echo) { struct termios tp, save; char *password = (char *)malloc(BUF_SIZE * sizeof(char)); /* printf("Input Password:"); fflush(stdout); */ if (tcgetattr(STDIN_FILENO, &tp) == -1){ printf("tcgetattr error\n"); exit(1); } save = tp;/* So we can restore settings later */ if(enable_echo) ;/*Default is echo. Do nothing*/ else tp.c_lflag &= ~ECHO;/* ECHO off, other bits unchanged */ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tp) == -1){ printf("tcgetattr error\n"); exit(1); } /* Read some input */ if (fgets(password, BUF_SIZE, stdin) == NULL) printf("Got end-of-file/error on fgets()\n"); else ; /* Restore original terminal settings */ if (tcsetattr(STDIN_FILENO, TCSANOW, &save) == -1){ printf("tcgetattr error\n"); exit(1); } /*fgets读入的字符串末尾有回车符,在此替换为\0*/ password[strlen(password)-1] = '\0'; return password; } ukui-biometric-auth/pam-biometric/data/0000755000175000017500000000000014064326115017030 5ustar fengfengukui-biometric-auth/pam-biometric/data/ukui-biometric.conf0000644000175000017500000000024614064326115022631 0ustar fengfeng[General] EnableAuth=false DefaultDevice= DoubleAuth=false UserBind=false isShownInControlCenter=false UseFirstDevice=false MaxFailedTimes=3 HiddenSwitchButton=false ukui-biometric-auth/pam-biometric/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in0000644000175000017500000000155314064326115031245 0ustar fengfeng Restart Service 重启生物特征服务 Authentication is required to restart biometric service 重启生物特征服务需要身份验证 stock_person auth_admin auth_admin auth_admin_keep ${SCRIPTS_INSTALL_PATH}/biorestart ukui-biometric-auth/pam-biometric/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in0000644000175000017500000000167714064326115031066 0ustar fengfeng Run the biometric device driver control tool 运行生物识别设备驱动控制工具 Authentication is required to change the status of biometric device's driver 改变生物识别设备驱动状态需要进行身份验证 stock_person auth_admin auth_admin auth_admin_keep ${SCRIPTS_INSTALL_PATH}/biodrvctl ukui-biometric-auth/pam-biometric/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in0000644000175000017500000000163014064326115031614 0ustar fengfeng Run the biometric authentication control tool 运行生物识别认证控制工具 Authentication is required to enable or disable biometric authentication 开启或关闭生物识别认证需要进行身份验证 stock_person no no yes ${SCRIPTS_INSTALL_PATH}/bioctl-helper ukui-biometric-auth/pam-biometric/pam-configs/0000755000175000017500000000000014064326115020322 5ustar fengfengukui-biometric-auth/pam-biometric/pam-configs/pam-biometric0000644000175000017500000000026514064326115023000 0ustar fengfengName: Biometric Verification Default: yes Priority: 260 Conflicts: fprint fprintd fprintd.i386 fprintd.amd64 Auth-Type: Primary Auth: [success=end default=ignore] pam_biometric.so ukui-biometric-auth/images/0000755000175000017500000000000014064326115014634 5ustar fengfengukui-biometric-auth/images/huawei/0000755000175000017500000000000014064326115016116 5ustar fengfengukui-biometric-auth/images/huawei/06.svg0000644000175000017500000001260214064326115017065 0ustar fengfengukui-biometric-auth/images/huawei/02.svg0000644000175000017500000001260214064326115017061 0ustar fengfengukui-biometric-auth/images/huawei/Voiceprint_recognition.svg0000644000175000017500000000175014064326115023364 0ustar fengfengukui-biometric-auth/images/huawei/09.svg0000644000175000017500000001260214064326115017070 0ustar fengfengukui-biometric-auth/images/huawei/08.svg0000644000175000017500000001260214064326115017067 0ustar fengfengukui-biometric-auth/images/huawei/.DS_Store0000644000175000017500000001400414064326115017600 0ustar fengfengBud1 echnolBiotechnology.svgIlocblobs'Digital_vein.svgIlocblob;(Face_recognition.svgIlocblob(fingerprint.svgIlocblob(Iris_Recognition.svgIlocblob(Voiceprint_recognition.svgIlocblob(  @ @ @ @ E DSDB ` @ @ @ukui-biometric-auth/images/huawei/none_machine.svg0000644000175000017500000000242014064326115021260 0ustar fengfengukui-biometric-auth/images/huawei/Biotechnology.svg0000644000175000017500000000600414064326115021444 0ustar fengfengukui-biometric-auth/images/huawei/12.svg0000644000175000017500000001260214064326115017062 0ustar fengfengukui-biometric-auth/images/huawei/13.svg0000644000175000017500000001260214064326115017063 0ustar fengfengukui-biometric-auth/images/huawei/05.svg0000644000175000017500000001260214064326115017064 0ustar fengfengukui-biometric-auth/images/huawei/Face_recognition.svg0000644000175000017500000000144314064326115022077 0ustar fengfengukui-biometric-auth/images/huawei/Iris_Recognition.svg0000644000175000017500000000157114064326115022111 0ustar fengfengukui-biometric-auth/images/huawei/01.svg0000644000175000017500000001260214064326115017060 0ustar fengfengukui-biometric-auth/images/huawei/14.svg0000644000175000017500000001260214064326115017064 0ustar fengfengukui-biometric-auth/images/huawei/04.svg0000644000175000017500000001260214064326115017063 0ustar fengfengukui-biometric-auth/images/huawei/11.svg0000644000175000017500000001260214064326115017061 0ustar fengfengukui-biometric-auth/images/huawei/03.svg0000644000175000017500000001260214064326115017062 0ustar fengfengukui-biometric-auth/images/huawei/00.svg0000644000175000017500000001170214064326115017057 0ustar fengfengukui-biometric-auth/images/huawei/Digital_vein.svg0000644000175000017500000000251314064326115021236 0ustar fengfengukui-biometric-auth/images/huawei/07.svg0000644000175000017500000001260214064326115017066 0ustar fengfengukui-biometric-auth/images/huawei/fingerprint.svg0000644000175000017500000000413414064326115021170 0ustar fengfengukui-biometric-auth/images/huawei/10.svg0000644000175000017500000001260214064326115017060 0ustar fengfengukui-biometric-auth/images/Face/0000755000175000017500000000000014064326115015472 5ustar fengfengukui-biometric-auth/images/Face/08.png0000644000175000017500000000756114064326115016440 0ustar fengfengPNG  IHDRbb8IDATx]lYVѶIvI&CXș&FZh,O,3/ OBH7iFT/Y" InGx0$WpM߮tmf2vUݾϹ޺UDdXD΋e:;<w!'#"2. 0.?7]B<"򆈜ɨm[-˖/ ȸ 4!gl "޲qYWYLj;""8YWYuEm:"pCsnK $l#)O"4xӛM|eٟbpq;/5c.rpN6w_')y"nI52DFD\߉@lJvۦ&Q!#"v+6]v59tu FFWqtRo΋Y:h̔,lƅ\ ݙN>NJDLieOi;j43/l"% b/n=}b(ؼeK.J~^22Qݐ]d9'/Kc?i)\}&txGD=^ȸυG(t` \,]ǦS u߂ۖXu9Ih&peD  "(a9``Ht| h&At^"A_3$ؿ|e"iT*3o WD m2K44рOQ"!c4hGwt huq FDP4?G _A8 ="aV$㛨1Kk?ykh@qNe#",L|:'  |kFd Y:!chъ?`5^:"Qq"$ܑ%-0O'kTyF9i24!N4b7ڑPGp7gu^?Pt[k| v!;"B>D ?~(Z׍Vcd@ F# ? AZ`L ~/X=PӢՖZu7Pt<61-0DX|M'}OW^@y1#<~U^7M温4=qm/ϡL/F}=!πn5fNc[DhzhaBN#:uԘ`05RK(a46Lᅦ2;4 uA#:wீ5T ?Dmr~{4k=j2-ǎ` >N)2Gre{PsUO>FOuXE~K4{SmP$1Z:05:@Su"#", N ?A5"m`e~%P&8IjE^Gڃ#}P5]~x:O6-l幙:D(ڒk`͇!ձM9Fy+k(ӵr#?MiY3Y~ܧ1d< eh65. hlO+9ir؉F6;> N!dvXS@Q){ݸ+kOތgSy"v>Ei!:gm >h8 . G !n[ DtPyMMyɀfUPmo{<~^4wĭsRnk:62Yz%Gѣ]u벣􍥎=wRV-_w޵ͮogk8zͤ٪]fwvŤ sss{mO 0000tYZ;ti8BP>7D bnnn;K%"#Ax[ #իWVV^~0 ג;k}AEHe$F8qɓ'o'wP*;T.DU$pg'Bx Ԯw4"RI睸y2D:yv!W^Yiy@mK4EQT޷U*N:5&ĈV^Rp'Ĉ8}CqVMm) +Au\ XsJkT*wYu]whbbHyg颈H@AxǏ~I\.8s8 ojO*h*=Qz:88Hޓ W^_,&"LNN|˲ FGGG\m/Rt/oK!Ax/bUZ677waa@OO>J͛G9n811ѽ$uÙR^\.c"nסkMRaEnG e"5(f=۳ghE8׼hq(Ez֭Yʮ8v~w]7\YYz~Ǐ6Axp]Y=155U_ZZn("/nرQ놥R)9L_̞ۘW2U:>>N{lqU(=k{9F9nX(QN9SSS i ޶t; WqƨC&fW9Ј 㹙!D9I""4$r8NVi@nw|qV^Hc7n" =C0 ߻[䆈+++*z'wrA3EQ%J 6ɕ9Axa( Yݻwi6*=8+.pCN6uyad~ü`[ߙ;4>p.Oރ+/%^@gK .Αv vѝ1ڛ^މKIENDB`ukui-biometric-auth/images/Face/10.png0000644000175000017500000000765614064326115016436 0ustar fengfengPNG  IHDRbbuIDATx]_lG9眝 vkġ*P"xr_[ $Hy! *-TH/H E9ۨiӦv|am|{&O~|.`4MqsxDADڐi"o62 b hnr;qq^ )dN>k^x!>2`B4Nc#;Χ":){cObhe?'@!Үأ-;Aʬ Q2ǯ !_RȄFpé*WHʦ"xh76?e2SB;/1hCO.|a$,0AV;/OflʿD0 (W%2$v%il6Mc,2CF*DW=[]H-N6OgRҝ&iX;S%# "{Tt's\3S'І-#ZtN-S/L"( d:l$e]dq)CRsH?G) QYxYZSOLLpI&}Eh"Pi&{ , *Vauny aLE:Yg,ts]2h%g[(fژ[gR4Dls]&ijiA̅@q [x$HZfҔ&x|po87N6gM(5mРưtɵ(v Qܝ@&1k+$Ǡ\ӭ0Ḷ$! aKCWn<@4l<=ջH6vf+馎xذ Jdms҈9~%()]X{[2Nqz֞)[]*-\DNfFys[ 5w%_9;i&8eaERO.ga✡z"<ǔNp~JD9"."*p"&?ѯh?u"!N7&E} Q9f@@DO<}MGx|/,s}ys||_xxB/P&巍#"3> ".J;("|$lE-{ %lP<y>#:w9sYbBD%\> `n.__ 7T94@$l39"1"([nB G'C&0mE>6M֏HEs@7WD |PҔ"V"o7|`>Tõ4##C#N'$A4'Ԉn> &رB WsV A UM[sCaDts^hNBj:B ODA-숈ZyS+FD qh 4BF5$A aE4j5fjܮډl"ʣ94SP&ʜCL2@ V9=h$t/.~=l&k!aMD@ 4zbAz/z`>Ajd||! U94i #Ah:yQWMYG EFTh&!_<5aDaj8[3d݌ 6c .Z t92-DH0$egB̛\YMDp2c`sь", \}P;ESٺ7LkZSpA|8W:׎se?@FYFFFCuHDIB~>!r-W< 6-7]ZaLaZB7ĸu>Am%(X0 -KF~}P^nX2{)jQҮ^AEN f;Zmd.h9'T3.0'q5@pz|j["HCpQ0A:I\"o=4ӴB P~|b nMf6Pg;teô}=piak0ڡi$T†5n@iX5"ulZE vqm75P(/ Y-8$Em1b&5I DU>u_3vij|i"tO ZL>G^^ADDŽ,z-p 8- 4X'NH|æ;Aj_oBV,<+.E>o&b{T8ӅݻwYy߫RJWJy+knhq'\=FD\յtŕeY===Zc:׸1KҭlqǏ׻^%RJuݵ|>_%X' mXVW:=Ɖr\t]w'84T*u5!ĪmKI/Ҁ+;?2==]HKXq:ٔ?HKHJsϟJJ,Nq|AKi?F2Jˏ}x@Ήw4>[Ohΐ`}llqvzfplX) ! (Y$@""!!$(a/I&qmav+ql<ýwNmxjJ~={V8ayQDNm8# 9 9Y("&2Lv_-d2OȧD乜x`Ϣ{Z0ND} cUbKCl? 4AU"KF <$eRR HBGg$<$g6OWi ZSiDķOh>.0|8)4)1tIO/#h*ZHd,&ȒC]B:@KBh/ ښj%&&6mh66khC=ܛ@97mt&c c]䛪$5_t&!F{+?Dgq NSwKHMȆMKuG1m4zmDAgdU=@~s ['gu#cdžH )?|?g~4 i'sIMqѽ:qg׉B6]C1z'rWD!"1 I{/az2tlٛJk5yZt/h zm5s%SP~fD8k>\a%lt֚o'Mq{k^#}hH`{~}~&Ck|= |~`Il8 ܈F6;97|J{=%:51I2\p dg} <z>2caĬ{<ځu@'ϗLa[hǤ'1#Cw{axfs%#p&p!Ao_6y| =GkJz=}fVs `ED'PR2Dt*ۇ6 }h[vI1BiKT:Fhxkq:뤩 qOdZB[ם:/;BKf4,;L,IkdZrRhdMLr5EG 8ݮ>3؁9E;$o{,NhTꡎԈ8~-ԒRwtt4P@^V yesJkהRK MLLtz]Z[iˌaG n?6jڣE᛬ړ[j'7FFF ?IprPD仓o2{: Ctttu% YT,Z($ C駟J_]]+ߵ꬐ ﳳ;o߾gͭ w.{3pA>󢉉 .WGQtVUjuj7&''ot]5U*Eq{YzDsy]&q7F;F8RKkQºq"Ҹtҕ|x{-..=^<Պ#Gv0 }xwFD.DLOOxHSO=u>|xǁyQRepN"?fm, >*_mg^6 Cߺq׋B;^ jYzIERZ<,r'bzzU*WE]/i~~J쭠P8yC_N;f+EsA4"]N($vyN@ 9iZ.(z; T/PJ-eb5VQ" 5C(R_U*yp A]3q=\^_0/{ʝ0 (J,s,^6 <џ;R"JVպl6 A`… (ڣZ|rWf/_~. *IJK݌T9qwʿcD~V$_-@kp ;P<SK,ͳ7? k;>R)TׯYqZ Rj)^T9333偁ݾ`o- ?117DQ*꽽sΝ[Hԉ)?444l6i̭Jr#e+CcFڕ|(垞D*D;zm&`E<J3 FT*I;FQZ `.Yp޾rs[˟Ȝ)0 4V_KD[|9"*=8a3ˡ=mtVa1PB&|nAD޳qnؓW/cvÞD8ݐ8ĺu [V0Ƭ}y'4BMpIٓaexכ]:B^Ic-qS+5$myGF#LC;ϮBibn_Iq;mRxűTDeܴ[v :tҭkY&_s =9$ AWW,gFžSh+4xdm teikȍ"^Iy!3J6BgloӜ{gFm>$I2$)J'uh҈W4FL{aU?}K,FXyFkC,RP.ƍlCn`[A!Raf~,Mj;uDu&Jn³>Zݫ0MlrGxBN Yxj"JޭVL39ZװWek٫iRs&w)Y%4"hQc̪ lle LDV%2δc42K^^M/hhnLV6]FO[}i7Z3JUma2EL]Dnv7y6e]I8Ikշm!B/hW^DsvyMֹƱBD<d׈IMόvqMW2Mmu KkPGۈ0|8p k7ɲY;Ĥۋ4Bs/OyLLd2U=Itx&囖׾[>,géDdoktK,_^EЈȗE䚈<#"}"rDDt;Zg;/"/=}"rNDwxۤ6pphBA3zmFHQD>'"#"+J{AyVپj*"&"?/"ϋȠu"}ܼ3 M|Vwέ|]`(`ۺ%?JJj}o.=چ?{ց!Pv1VI?'"p p4^45 Xx|+lk^'"g_ƒ&~~ 1\USmXjFHeuW_B0 OƫE >6D<kP~ _}| KP @("m&DH(aҢ EC8}#'c85+dwI'C).ZWH'a;1fuYŐ#q2)yl>P%" 4pHH_Եxi%QVh%H؎L^o? Vq2 2_Id(=vD8JXšD2<|e;2#|)J/a=o`]cOc'tj[Xs<$2|<sK׀ ;_ND@형&D꒑iB''!鸑֔pD[ 9Mi IZVK>ծmnh ؉?J{K~ZfFx3I:nDP\k;>,V[Xm(b'gN`{z.kro7ƄP =ߙ@㽼^/_>M&f$ ҍW,$a;7p$(~I;/V79 {T*A0umV*nP.GEk[Z<|pkuuu… ^*S0pرBDZ-uAM™3g>5.J7o>h71m'baaaP(2{mJܹN= -;wnp{{q%AanUDvmm!\.UՏP,߭T*:mwۉr< 6sθ|02l^nևa /x e:o[u'b?wz~{Mzb1|@-r!'?^'Gi8,OH8\16O%/h3܃׮O'ʼnG]IENDB`ukui-biometric-auth/images/Face/17.png0000644000175000017500000000723114064326115016432 0ustar fengfengPNG  IHDRbb`IDATx]oGNNPA uZ$|@<@y@OF H UB !ٕ*]ɖ@@}`I;ߏٽ=ߝݟݽ77|;($@rU6_,ᄂR 9Y.+@G;]ȭ~\%9OrOvlArVd佨s]O YmNH4elL+v@rFd$Ab'V~W[7b x7 $\sUDR$'p-޶fe(R  V|B9 =1n8igМ!aCn"qd$b#@Dc:&`l52BD7Rvv8d6&h`{GMr>v~j VHz'yw>ܽÑhCjHLZbK^0BOnlfE`;2>nʿ>Ōs~:!Za2焘HoB-s d*2rc+*a9M'Ez2OrCϒ;8z(+y=^kL'R,餸R9!qQb'ܡaAȹ]&q/T`͕e{A\HQoL?є $}kNU"`YT ^cSGi_i rA"Ifm"=`X8 rd)YdA=ly84X(ACfY# T1D?u, " Aր_`8iګ{5I=(_hzu#!BB9WH&19n,p!*OehfW\p}o&*5IoG4X`n2żU$oSu.C}$7ͨr: 2a`4-'<̢v _YU֩MFo"l::Q2Ư\kJpBz!*'BHWM 24A!{$oJ]^+d c1pjV4/'|L2K*}Џ]~#Mi֗U>i*<Jra 2b`>ȋag؎ruIXFE""d"\$="OӴ&i2ftXXn0€is2bv3eEo ј٘Mk:H4~+c~rB)Qy&3!jQf{$=<~Y$)%!s}(hRMfY+ӥ=CSM"XUOd hrPӯ}U;vLul3I.6p'-k:D/fOX%yK$K(S$O6A$!#1 \TZؓIY* y;_ M_)?b৲?` oZ;m9\s 6 hhpfaރ$-CW%ܗ'ge? >0d1  n X{dFv+^W1%c7 `'$ϫ0ZuIhډO#I 13"x$ Lr&%W"HԦ%t&5Sy`\tQR{>Fg !0Ԃ 8"/ZlEN"?pV":m&8&|$QS N+"b}BUj4o aDjM6#/tQ$iNkR}؍d"B'%EkE" dX h ԂF]aF5%R:BGR!JMQUAEJ,@GKJ=>E_ݖ_ X!䑯v"BHE(lKĹ&kG5‡ 8ޓxgK(\t'o$FFFܹs_:o맋sjsAذ}[[[ ybyyxʕ㇇I B^?'ywzzQ̅F[aRW^]uz|P8>g׮]{4bkkkhlk ATڛr z xtSfJr19rq}}t4|`0o̜Yf=o 8=E}=#iNAY/z/k*kuߏp'?)=h+\030ṿ/h[a¤Px\2DqIC~7W$t "+3 C$E8*aa[$FA50X3Z #JJHkz& pDP0gnD7 > n'o$42],H| ҮdGIPz ~zC9/<ܳg,Pn!:q&K'BKqHy鮫B eaYѷ̬?_]QuLtG7YjJT1#Y }o~'"z8< f^&13 EBQ&}Hx5#'jv Md3oCFGxT_"hT(p7 0l¿` ifFaF 5Ri033ɨ?$Gp;>.A\ +ci> [ |E (G_[8"]ӄÎF-5*xyOx7_n7[UQ.4e?rb q] ֮{^a"͜ \!s;SAXp.DNTVw%GXa&Ci tIQh-M*o[ڽfPNW"Oxnߧp^/ /̜'ZD^Xa](}B'}S}Euzsp?Bwwwcmm5t`}}}6H"aPOZ^KX]]nZRJ X5Lu Dtmf~&RCĈvW쬮nO*(b63OJKIEa"D[B@.{64G!lRR%`ZemuXLk\,//"v>O#S"dJl"2qBD4TV+!JƇJ%W(~TM J%w)HuO>q~~|# N$X[[kZ>Ѷ~w%ёGAv3lL3IQ.{"jz.,qܹ41 e3v%Z^RDuIbhy5FDRuB4Lc0߈ ƈmHp,s-#D¯j;7o޼!mFPz%!ī`Dr*vL#v"\*Q$ xGMU Ee=}BV{%¼ɴb'/Hn\B̸[!v"Tt'p:ZRZd06|=0T_uޱck֧GC{R@="BѸ6FDMjvb4&;Jv5Dض}:h4Yu^.f6#06"gy|蚖l~mRjm׶׷o~tΝNjsXpR Z<8ӆrSp";X(9Rzyz^7wgc@m0S`8#"%oTأFBZeɲ4I)=8귧w-en_k<2Q쪎؈X]]&}"ZXXH8&tN<$}!LTgIRyz޶3:c----0mۯF+p]7KDW|oLLjUY)<3O3sP(<3e'ԡ)QϘʊ11^qyS׵ZyT!XnݺtvrKf[A"ƅ7o|ށ/>hR9I^_}¯뵴 u ^oĭ&k r*>"t:;IL]/\qK@D?fRy5-B 'O6l*'NDZj:֮l6YkEǹ9cYu,&"t4fyIxEJi|06aDJm/,'9cK @ ֬P(,8i>JBLfD:'ED^^U/QFڌ#xbƲq+ٔz%z. 5"d@RIڞ'. ۶sS \mMwH m6]ap"5Df )(8c߻H SSSl6Yn\*P{Iy{@(#uS5zJq,o@&ya2e~lC 3?H*RM1r%Gc'jzhӧ>}5Ԕ^똸ࣱꖂLRnv*Dz>HHBW,;\n+\&Z#ƅVuC2X~>Q$h4<ϻ_ѾyiX+v] h_JlJe*`UЎXRWϘdGMLDT*eY333n;+ׂljT8uBݞzfBV69;XзG=my{ICnBp9hbcZmEu﷈h߶ӓ$zerG绯's\C$8ǮwC\#g|A _xܿ\~7 %`9yx #xh2Hl=#iz\|=,ϘDfO ;fLTԧSmIENDB`ukui-biometric-auth/images/Face/04.png0000644000175000017500000000655514064326115016436 0ustar fengfengPNG  IHDRbb 4IDATx]Mo~fvE"ekC\V+E"+5j^R^^ /Ha6)z(ړąpJ  1ZkY+"ܷ vvwޙwgv$,_x7|Umq"hR`ґI& $]#MƘs2S~;~ c؎q\"z{Bc~DD -ah _\w"h'v:;9cD1~ x#ݼی 1HZ%h H[3upIKc|x.iwm~5n.e}8hFRBB蝎2".^Hz"A:6pvRކVYI "\AI9 !'ҹ &"@1WVHLn16Mh#@d+q\/QX9sƘݧV<͈1mP5\ JN%&GA|!=k|J3~Rd]i.BLIQQ &xGQ7hDԀKHі}kO  r< 'pw{-|؃BN$~uFԥnq,~HH%lAp  |Ux9Fjkf,d<(8~ H8% lh'gM`_Z˯R\&~'2 r'!u qќ*wxhDOU*ضvt]ٮϖܺuk+bX;<" ЄCX,>#͸!7;16""l DZ3n " Xi_LX`&` "&/_6@4+^eBx,JDcD u krn=}vh5LFDVا_U,*0BwuFs!c,9??*|N,frsL @|bc h,nyi شmۗ}>JvpgƈdT3LORAʊ2ahsb ϊ㸹B ^[z}/J=Um PH@\xepw---}:~ vF\92JҴm8vT*E+L4 /WVVi&yA.2̼;A(HLwJs 04UY}Vaجѣ(ʡXXX"1ι]TQ۫HGZ8?l2 4M qT 4"ya濰08}CŰ1C D44MS0041TuNJ @ Y",Jiȣ$ι=22"A9|Y*⩗mToy?['5M &+qs1ЈA%byN] VD躞Լ4*0ƒabCTOW6م&"6Dj =pmv dr *mI;b.D5CX*peLӌ)r" l۾###OT浳'lrp"}9rXfF,p?{7Blllض}1v9Wbi*V ,Wt0 cfѣvyFJYABl6[ORۀd,JQ/dFjzC|L)/]?^]]jV(e]/cemYiq CqΎ7 +'P(iSba|7nnh0\.wŶk{DTރ&&t" BJӴLk^eX+0 ۙZ6l6'x9mD"aQ($B!B^~t_ge ifl۞>V04X,kv1vY^l^Y^^~p4IR~Q0 -U'&(zMsy'"}mq;p?qp!dD4+uOoGZmI{7.:OO#Q'~~D$HŐ#"zSN6 IENDB`ukui-biometric-auth/images/Face/13.png0000644000175000017500000001002614064326115016422 0ustar fengfengPNG  IHDRbbIDATx_lI^?3c{UV$w'dža=-,'!B H#BJxY!@B ݃XqQ8l]x8g'~RtWWUկ~]3DdLD΋Ȝs Ԇ\ϋX gۨ0=~An.xD䬈ٞYi' E9pڷqϭ "ryK̻cDdRebDD1&=p/ݑ$ĺu))+ցE5ƬuB_h: '5MuU~$eKy!"34x7]>ꧼ/SƘ{kpO=n|$UaZ6ޞ['S%^$\f/f]G~"#O"F 1;`2"oȅJgǰс=-P7Cb7ˉjgdAĜvq﬈e(w:K9-m]{) mh3RrkL"q?'bE>AkFi؊9idp+&Edyu}(6&VGڗi%GZ+i>x~8swzK e-]i}޹Iw6]Lέ9l=u&ײ,@{t0d]sHr[\ԏgRĆ[aNe1aGx+K_wALM^ȌMxJz͜zg6?$^I7 eif-}Ӓ!Os4V=G-x[iotfQطtb]mEv6OSooZBlΈUP.ƍ%'l'N#ļB⭆՛&]@7r7.k5GHPp={#KPnW{{U>yz,.y&j"Jݘ&gr^}絭ݫiR3QmKɊoi=GˌcT'iFԙ8Il"iǚy`3o1Ϻ16=駚%׀%aX !1Ƽ>jm!-\RcWEDv;UpHǺM5ʺi?di s  5WE$jƘ=kJ"],%16%LR뤓Fk`hFB8}O5b2Bc(yI.ƞPJZ>]ӿO<$ I2Q=9 zP^ @Հ^4dWDY]3,iGBld#/9O8 wl'/_jX}.BVD$1 |`Z)xE7/-4"Kr"KX/nX>s : "OjG[D( ĂwD4<K׀S_W &p ;WeGK*fd1CP_SUkfBo5yI# N 5P U2Z~ |2MV|K?=b1{ +4GKjo`Gyu~o=Ě?jEVʣ_>'+;yOk [I#<|$!9oaMohu_|_ywF:^ X®cɸGlKX7f~XN4vHܠ{jI71;F}$!z;o| 8]>ܫX=šAbb&X%#;^'jk'=K&D$GF"0:Mz7~fVCn&ɥ!pVN}?"vs_Ժ~aMCư!Y?Ć}L.ЎIPQz' _PKs?+؅c+ƽɾ#֍a͏$ M_~=d;,=(%wiSD}X7JDr$ ~xyǎ!G#j;vD$I]N&_i'DF>'MN> ?F6s󕫫if ܶ oWj"R/)JQJNK >)L~) _EcL888OX3rE)Ǿ)ݪuu;(˅Ǐhyx333] 1~XfeL}ccf 9rd=zPE ¥۽lrJ2R׏G]JmfA'&&O ¡nW. "*@E~!KKK (*_^^>ԍvrرc9T*Vn;333(a.˅VG O:^kA ;Y0 D@{u|M!"UZ6ڪl+"[o+&1fU<7DT*FʽRT6 w y p-<ӭ6JR@D J2hEnj>@J܉(˅0 J'lkmmm=sm@O-8q ƘAN/⒘;Z/p_C:G']0 _65y\*W\ib:NPPj~pM^hrpԩǏNK 0ȝNm!Bu&;P,RVvJe$ A&&c4&0 71zgy0 _xׯN'=mPޮ_(˅N:ْ!z!WEtʯK-4I2||1(-3tocw⯎?C6{6Y ?DA ?>4 RAPf|WIENDB`ukui-biometric-auth/images/Face/11.png0000644000175000017500000000766614064326115016440 0ustar fengfengPNG  IHDRbb}IDATx]KlIgq=NmdK&I^ehFV"#I"n#֘Ip041j2!b7qڅtفM*i.}o|HTG/q8MDw>J>;;>46I9og!?Qa1K1O srk,Y&(|к!6RB&7+ %Yx=Aeb* g'8] d/d\f["j(ȟa:?UN aE6,q㸇n]^"F40^sj9 \-?I'p2$^6H bROs|nH!\3mJoޗgF1΍p8b5ny4詃an\2UQuAQ d\Ƈ/Trjjz)Ԃ9Ty$6tEik݈$B[ 9D{7$[Ls\ ɃtZD;>RɬEo"L uF1B\ Uz#ƽ0zKW+jNڛ kkuMEԸ6{~ ~4B;/5hewۥE_.A@7쭉(rueme@j4})| GBbvW l͘2y71Mp]]FyYޛf )OߥDE×U_yz,Ӂ!6QqԦeNeqn;۳(xvDFWl yoM@%(QƜ[6Ԅ$\F I_!"#0 njD3: }ʢ!h$@ Nm(_&:=m!v26OՍՐjp"P,c_k~D|5"qyYHPR ^c646u&@ @ R_3Y@=~V2}Yp9-5C{b'P=v2,(AkihR& %㞬qLNEs P°i~O&0Ul׈JD}v\#*@'*<ɛP03P"ξ [P:{~;ԃk-DFBMI>քD ۜMn ).M!Į5!D0).PD| =(f02L}B j =px >eN'bӔA[|슈)(ǗA 3|_@Q'L2Q 2R' /8o][ &ס|*ڍE64|"^Z'O'P;7|2AO@9 }Kpg)(?sڳ~%<_!96M(B"G[5O@M^E/rA9N4Q`,ʵA=,|=|e E)q>uh;( 1a߈5i$P$e(yL"t~V4]#s eB%,B (w%(hk@ W>Q(P"ڈ;" A Wl7c͖&t2EP +9m7M?sfTdSmv\i@in£6Spfrq>5z+By |+Q\*,ץ4m+ 4uq44gCTU" Ǭa_I/A0巳0׌>C @oY#5If'm3M0KWW`xQqE#t́͢6IY"b'&0֘ A(@9JDCb-p8-)Q> SVX(X3-}PN[;JTXzYW M A28!>nP F01H{@vJ)6 <btD; %cC w?0?rJ+)W4)HIA9a#찑aZsg[UZ Iס&jcϯ s+h~`Ck9碏#'\NS&8 5ͱrbܘ P_ BfᇧA36)\_A6YNXqeixwݻwgb>n|gT:!t6Y~CY9!Ī2;<<|e' @Tzh59c Qm[?"ϧG\=q>O,єӞQwvv򫩯_ޝdz+]#GFFޏ,qOJ5۶0˽jqɓۖoll,f2?6"4fff5Fm k1!a);<<̺`FDI4xwq=qqkB{%Ֆ}may6߾}nDV8q:JI/ӊf8eYR>8wZ{F"DJ)]"8~xo3?ql)qA45| "BJHD#4m۾eY8U=+ @DsP(~W0$)J⨧^$NXP(<+Gpft7 Qĭ[Y˲4zMO<*-I-IǏ>""lnnfM-Emc@!Bk9;c7h"㪃uݎ-CD[[[7o)q"DZ\T*u?κ.!㬫VHsjyxxb_)166V*J`ss%P9/&шcB޹s);w| XB5U#.q% |>MDIOyh7G8c MBpCCCLfPB' MՈ^=t7הK~wٳgc +aK bffX,/bqN>v!Īy'O/ƽ v"2,<PNJզDZ{4xSTmƍˍ&DLMMe,fYsrQ.{8u̙Rt@ku]w-N!hJm~X,mw|>)e60 ӈ\.7kBU۶%SWN:uc7ej-SSSC$8ՈU'['vԿ'䚴gqI ;/'Ӗ= -[/T8h 9G ~pǿb{<2ՏӑD@)4М1 (;*>?VdE7IENDB`ukui-biometric-auth/images/Face/06.png0000644000175000017500000000712414064326115016431 0ustar fengfengPNG  IHDRbbIDATx_l}?Gȣ$eJeFm*m0jm$@&m piu!V`_-RFP |w*-ڊRDׇ GvoW"`f;fvfȰ|UD0a\܁\*"Ûe2l.?7Bng"򒈜Ϩm-D休_s?x)B,λ6n "ߗc&^LٿDDR*EXYWݺv1\1RI/-B#pڄ g0|$47W+h2$D 4HD(icKȟ'DK "wXOB'">Λu"_Ndku&%J6n'ha#-< xNK_n |'4L\pv'Ax{6ms-ZX2JIMh6ǑI` Kkni7L{.5p8PJ}z?֍=lNUC`IE- 9 ګz-E`m͛\Ͱh|Ϙ{ei&a-OhXMl0鈖a i ۲߱Ԧn:@o~*$cڻ5Z^iNކϣ{?v~ = !l?C,Yk&_ۮvh0$%†Ny(҆A`6#w iwNtSGmg6m$Dk~d1c_@!GkߠGvShsdDUm֌o~] Ԁc8`Г2Nʎ o'uǠmn X~m9g[":6³8FN4/˴2nzԖD8@%}cӈpn"@GN.5I64hjA?4$kI=GYI: ֝u?̈́;iZ@=+aK&{h0a{J[>8vm[YYmGP(|O'rCg 'Г(́;瞻$nOh knduu |۴9,4;N~^J8Jl6? ;kI-Tա(zUC/mNW QX[[{I(˷<ϋ8FGGG,+q"D0@P'w155՜y^y@R)UVDx7pܹen,//Iĉ8wrZyw"rF( n }ԩ˧OTy@\rx"Dar|3<󆩩]WJuPH"@4'f 4't;>9A"Dܻw ~*^@"DǢ"җٶLSu]{p̙ښ$#buu>`z\^PJ%ԑgϞZRJ*J4֜ Ԓyǒ;KLOOEdlIcc{_0O<9*"}A;JңI7i'oT*8GzVK###zOR'\tiX,|<99Mjo [0- ].om)$ C;~mmmX,~lgi!WjCw}[ccc]NpcJ#EW]~W;AR)5"nסkMyYfp=,H.qTs0 q(}Yե뫯y fqk׮gi*ND^ĉ"y^Xzy'O6axw+j2!=&"}>_6 CߺqB;^Jj:F9y^T(nQn9SSSjZO(:zIv?7/+rʨy$fW9Ј _e\a$ K/rEDEHJe@)՛tI 7DzRj)%4_n[䆈Hgϐ=EQ{W!w`qqNZe8'r .D=Cq\ _eTTr=eND~E ‡i5;;;gqatbbRWDR)155l6wF./}9J\zXEO*fff2۝n Mk]kxx9?twt(usR8<>FaWaKB pkbEj:FjDV;|.E_1DK7 Ui₉hײ˞Dd1O/eZ=yɑs8Lǿ/&Gf3FPw6 v y."|[/vkIENDB`ukui-biometric-auth/images/Face/01.png0000644000175000017500000000501414064326115016420 0ustar fengfengPNG  IHDRbb IDATxNOUmDDȅ+;Sx7#MafeɋHhL@vuiqK U]E'ש:UqG???+ IO!|9ƀPn/2D|O5NHy><ӜThwcy] ei㪺v@?DDBѝ([wBy^n7ǩ{Xd$mS.R+#jD\K#bR6"1"(ʏ%8VX\EBȏ70$DaB8/%߿[CiV!"lBRR6w9omZ!GQkooodqY 8Q@x< 1(d1 ݻi_{4ͥt:$1D8#mZ+Djǃ`snDZ!z']ocV;Fďs{cc1bb2<ǝZvWQVqJrOgZy^N #8⼈D"q 9h4ҺC`:*# l>2eRU*pιf56QСB)L.t:CnR!bjV|_W>dm4\.WJR߬4|s~-]E:l60 l6m۟+!wCUPn}L&d2 DbfQ\Lgߧ?̃177z qe- aR!Z=ιM`N,(ʚWeB44!!*4%S3x dضٔì8ce˲ε!fҔR溮QsYX[[{9q:Jv%Ji+b QBxv%8T@ [8^׾A!qB2.B "=YzxrrK)eҼyrHB4Kye{{{ (aEVuEu[:Y_WD_3r+! aB­p+! a*&t t=Bvغh .$ 6 F$ !lLBŶ!D^.5čxQَ@iB4ͥ^oD0~[ST:mH9\bm׶7O<ٕ I9\X 'aF^9$;|)B4eJ)}5Vx ðj^Nښ b"j=p?B{{{ՔZ!YQ aJ(KX^_iY ǹ9cY phS!iY[[{gbqsn`vFu\.wm `YDZPs"k"˕|_VOtD)eDb_E|ՏHg⿊_xGznꬼ@"K-"~DyFħp CI$uĐIENDB`ukui-biometric-auth/images/Face/12.png0000644000175000017500000000766114064326115016434 0ustar fengfengPNG  IHDRbbxIDATxMlGv=Cz$RcGbdDD ;q$r([`m%|$!HK "XBY0$$3^y#:ZBC"/z.6g8=?P_ի=ADNђyJ!"Г9ݬ«mTRo " te׼3"\޾Oo,S%Z?Dƶ=7`ODdBu`DD1&oF8$ aH-]kI .hp;;Hʶ"BDo]ov}T?--`pu NǍ%lyB%5JMmZF/ud,yqs? Qٓ4 M\8HkLHkl!OoRܵλ".w*"3λ<=wADH]Z˞fI> 'vkl]]T-hIp;ArrQпߘDj,xDI)%rE%}FKZT+JG5%/"B .orST̮Sy>J.oMO>GF+L5o!Ir#ߟ]h J#]DaeJI摖BzH2>\]}Kڏg IJ ̨ -CiI}޾ g*m"s;,艃n69e5Ӯ\!C{ݪX-mݼ t+`)EZ:nY[|1YL)]Xk[{I]oOZBllNWR.ŝN~OOEy I^5<̛tyoRrׁ&'kdO.zGܾbVת5L_;3#<%7KY\ 7 lgLqMh[Gh[ ^7NӤ>~F9zΈ1*B3u."+.HZfpͫ*!igs 92ol+BL7%b,Qâ~%2jjG+BRcEDUqHņM-̺Fh?e,i|h5Y+ADa6  ,-G!Q_ teVA߄_!KjDr uY rhB 4)Ȁ<#"%-* 5ZGADBٞ\S@:kDttB&|Y7'C"2ۗDds[Dl[?GPR*=+UZ, n?5tDLjo c |[D.`F"r O2U"`'!<},紼iqJo"2ԍ1ЙeU|=R@ǒ~b%:7!V1VFP_^*OU $'ſaзP_z;P? |%l+"o0CɃEOu7a` ؂9E"\c&V=9􉞷25"-CwD_1qY2Sɥ6C@D>)u C$n-?> uu=nnwR#HSf+к8$"e].DBBl/?LBNxL2A<+ь:3}*[$dDmzPҚ!"ruWHBuH,)_/`' >bs/^;CáԱ /"1`u=t xF9e?7C|2;^.,0mg=Ip'ƺj;iG~/'#d KH4&³ylظNdNck,IE0 vVhDB Xה[*vup! yP("Y-"->ElH*6nwOmaЌ zקIǁQy'i7Id IP%ؑ N>){bO F+>'؉MQ$q9i }~AcDoiGS( d%ЊLDx$.&m~YO?x8w]xYkùIՌj) ۳7];n}-=†4ܜ )Z ̾HGEn/ w+ l &٭XE5+v7㻚@ 6vlhTqX !$0E>;=$$8Bܛ#/bgiE=4 7k֔%%%O>:}q |vH, AEK>moy`XP;M-*ó*GݖL%F2P;MX̍p6tX+kZc,wH(Aal k9gT1!(IuTMuW3KATM8oHHxDBnlv_677_~hmmmԩS1 hѫ0= żd{Mbr99\=BFB)@'Jl\..T/$@>/WՓhǏ b7/r'bzz^V8DQB7o?JZYYhlllm}[n `8 ;cccۥW §ϟuw[Dh@'w%>JDj[[[Ý+" B J`lun"*ʀKu~?QTA7DՆlDQt[m}C G=Vb?+Je(8kLjU +J_EOQ.(Fl޽{ADƘl]RƘAӓ4zV_`w9!n߾bEcܹӓ;w>3Ƭcj˹}a/s?Je@Dq\;1\.j#!fTZdV~qݣ#.Q)Ri@]ku-|nmwjA0mj~xV\T8mƘ8k?^wr_*:sssÇD..sQ>&"b688v177W ְ\ӛy0???VB\_y啡Cz (j"c[GDKi Zm~T*CQ `8}p 7FQnY+ ݞ(z_ u:-sssCO#RE"JOдBo܇ 7$!IENDB`ukui-biometric-auth/images/Face/14.png0000644000175000017500000001003514064326115016423 0ustar fengfengPNG  IHDRbbIDATx_lI^?3cDZ#{w{YXֹۇs88#Y'$'$) $N sqNfQd[@r؉OOx_˝wL'JUS]]Wu x 9+"O)DB rrr=+"k${Y@nsy΋iӳ='sקJÌoZ;/]{6n{ "*#"`1'b;XnAʊ `IKƘ<- FpBS9Www]9 dw m4_rW^Ƙm58$0+VϭV)ٕPm/f⾎A"D\mG 1`:"j` Jf߰с=Ɣ PטּMz=Q+ b m\;'"duW?s鵻І=#5i#]fz}/|"Vn=Y`XjFi^=;'aDBgEd;V!:aK<*1 (k "U=2)Q #~QuOzM r;Pk"r## 7rp,.x&‹jv#JvL39z#^{g^+}I{D.%+rB#=GLcT'i.3YqD:Ӳ5 g6紿O'?ƘЏN?Ք]AhM< xA^1V2KjH#PT#znaC`.$X(A*6 du&ݏ%Bǣt d'h7;$4ڭ{t]h_؍u=!BCWH1YֲU3zX>*]q89Ĩ[FaAK H,/p4x1nދxĿMxڵџY x禽viY8XyU+-解Yڧn |;:}|>N\"Gygm;_%KI; 14 `&$~^y 6(cy W"rěl;-vI_]tZO{4f9[А~,Vɶ]FO}iקmř$ӪcXLDaE{԰s؎r}ʺL{_Ndi{5DiAF\X%E+Dh^ !tx^3mEVɮij 6,.1 &[9_ia0>l+_X-QeXҿ5Q41XC@S*f%B.ipDŚ'k? G҈=5}P?*pK6u/5xw? %@S-yl ~H#!V'Oe? `MipK࿱`G+XѶg XM7Je bUw\gy hH[DWhN+=~ ;/cM:{'s#\՚G'g_3n#b=K0uoG~Zkb# .|5-^!5,!2 -pD yIR%a 1 v2'NK>zga8՞:#r'?mɑ_pEd'vD'¥f8""}Św)W'kDܥ9 cu-,Vkd쓐~w `r'ܑ ⛬dyKayYՇ(% ڌ=]zY`[껦`| W|Sh99s% (pE#|P4"ρ_^> C aMmʹB#X-raWDaIhdj|Hǯ]<7 "=v宜<_jyir5Q3I(n?^L h\/'5a8uְ6N>Ѻ;qTj?{<G%P1'4i>鐗kّp(AOTr(/b':M]F79d{B3XmKKo{BvZ~}O]2<$~9y߯$"EcBp%0D4"]֣( D" %b^VǃIt%ک6uJR8vA{KN8ڵkc^ wovU@ᰴt,Bpcjjj+϶?b֫z;϶խ~wwjDdVb8 ]V1yj:EQ v'j:֍{t!bkkk nCSax8n10D nݣT*m"@QVǂ h@juQT aNJ[ݼF!1h7*nX~j5 7^%qԩz^P'{L?:qڵa17zڽqmcc{q]!^ݻZDQTwɿsDR),//O8ݻ~/IYJReFܼydEA^|$@77o< sclnnB(ZEQ~c̃(6>|w8>82::zP(vAA CW*ǟg"T*mo\re+obr'bqqqP(j~pM׿ *J_{z 0 6ENs[.Dhdw677zmwDZ ƓϙM#_>&0 1Fga>k]M'eqqq߮_?PT #+1ؿCB6=__Z5_&!||)(]ow8(Ё\9i#;DB"JICoy!_{?Go.ƦAIENDB`ukui-biometric-auth/images/Face/18.png0000644000175000017500000000671114064326115016435 0ustar fengfengPNG  IHDRbb IDATxo$Gn6"" (BEB\0xx/ l.BHH .7فF|zi$I ~1H .7X$5޴tpl~v@}>{IB=q3TSzi[A6=b پ$ɏQW:T8\FIKDn TEۅqȺ ,[q(MAĤK#Iֈ(w=&G= (:$4=FADG=.g!+hLiYD0|:P~Tw&pEE$귍 硣fI.y1m"")Y+6hW>[2u: 9K+XUЂ~/ ~r@^&Z˗D`&m6k6 1XV҇Իy?LXt6nC &($IrMD.k]JP d c+1cNuMӊ_i,9+Oh(8t]F۸iݗ]=l*NѪǰ&bb1Kαm}#)v&azꇊ#mzvO"F9ih75D x*kDS&W4rM;ek>PЈH+P& v~3YDS9ٓ4CcSfCF8L,E}$Kcd?zRt.3r-?uL9I uSZؑU+.]RkI]]Mӡ !$`b]['LxxjDIWHDreϹ2ܩhύHj:<`$@j$g"ѓUg YP>g^ ]װ$ I[!'$H -qRR!2"%LZG4@+Ze/R}Y2EsOBT"Њ2,#XgmLN RamD|.省Usa0 cAMT+a_U'T:MU~6ƴ|d D_,h{JU>Vak!iŚOUd {!ZΧ<,N os;ZfXaQ\7+{:Q-!:i^FIK¸TPnUCN4-K: eb>FGŞ$EN-gV "woH$ɱUCG N3V}/) >O>_<CSP[Ib 8VV~'Yh I<9!% ?# %"~~3r"D ڧYxkDa' [r3% m%GH4f$D%zQn}i~~۶<"qD%A{ϐI*"2 &exx;G+##Cw#aH9$9)PᛴYCAUyРVE(  fxR CMjȀ,![HL{p+B4Z{L ԪQLDH Ocq˷> % yAf@r;O6'jo&lgRՓU"-D##œ1#kd=22["Y 88p'=໤ [xLD@|)dGOwHOw1ddJ9 >#!=9-fٶdd~/"KB޾~x?3ׁը ="22%onÅ_ g;[ EerT41۾\>JXyB)k ]<l f9" .r~2ٷV!pM끷C\/pt Y78 E$^OQ';xn[<~ MT#Y Q!ar}x '?Z%0OBByfji 5!$ӽח(CR8G%FZUKq ּxN{6q.xP &%+;ش gr0Lno[\a(#Qy& %Y&!j:pqG”CNߦM;3k?sC]+ RqmԇdN-sp=bmԄ/n֤>k* K_Д, -?8X?2IENDB`ukui-biometric-auth/images/Face/09.png0000644000175000017500000000750014064326115016432 0ustar fengfengPNG  IHDRbbIDATx_lI^?{qH*!Gp67!H{BC' ΟOȾ !A'PK(i:$,ɝDd/Qǎ==㡪25gM+_uu[_Uq,"s&tkk=.+=$R?0=J29yWD.TW"rvΑUŻ9!k^[;DK;6n&n#E%"RyguwFݭ;&te~zf@h$5b?>>DR^?/"D>-Zkv{c_tv6pQ). VS~$,%nquJ^ʿDn^7яZ2<ّ4632r!b/ܳEtG@hcك+Eb}7\ȃ9.+"2E 3qM~tJDBzֱ]En\ Ex>A\km{WMs].NEDC,f/Ȣs?@7 ̣`5wM"`aIqk3h"$, 1zNQවC3pWƤ,OE vĜ;'7j?Ъ툰ns5I&Gu;oM_#MRR%BDfymt}/o+?Fh24]1nOiMm`1F ^h@k5h3Cs-+= +TB_1֜lot( 9vClǁ7e{MDlm+{҈C&X:'h=dS9Zkh{"Fo4/q֝rMN/+"L3 lODV"6i;[ l (h󜟠MKBt֎Ki%|\\yфt陈X" 4f%kkڑ=d;a[oۑ|&?n [+t\u'8n'" DPpX(?oINd&6cl%mFL$l>5-Oc 'uk"$Ob1Ve=*܂ɮm`%n_?M[MhnֈWpIlp3Nkёy۰kڑђ]ZvM MO ""H0VM%FFت)nz?6aV#\2 V5;Z͎59u':[v+q%Ā&mhk WѵuKJӚ!#;?YYi}j@)p?اYsJk׈?_$MJkR@bN_Y*!mvfl7`; L8L swú9nmX5V[Ò~+CBVrr#֓c#&ΆIw9Iڄ$۹$CqBDdcYa獹 xZ.?4WH[o b؎B_-[XX8tP(Aӟg^pΝcJ7<ϋw+}|\Z=EQjZT*Fq@D>y8{8䕗{_E+l7;@D6>{yʾ1(ZqC"2y^۫\#\8ud}yO8OBlceey''O8|y^ټlx$ۧ)E$F ^V }ǝ;wEQtX)vݾv޽]_GJOT*9qʿmDyUh^bZ{!C_5baa ^YY4]v̺R baa@V{.TJj0W\TJq;Zŋ.g s";!yaɠ0ǣ(:&"CCC7oMLD}+1׹f \.?{N?w\iccchLy^EzPH*IB j~4QTJQA)D琓Ed_ן#8sv=ևȻ"r-g{e!""~d}Cw3kk{m|V안|.)2S@Y\c}0MR7;JD@)߃U-`pz/2`DVZ&m]8TJ{JFހ Ut((p6 g,X- /W$E\A{A౗_fp%*<{4)}IMJ= "R7e`^ߤ[5#LڴKQRt1B7@$XqHIZ&Kqo4 X̘`qB`/&mo 8 --TpKɰc_SlQS&o~`Sz`~݋ч^<8Zt,2V/;WQt ?&?B8 z{P?qR B=ǎg_FUo[ $dId>Z5I{žotW8uh5 E:¶6)_W#t%ȘJC zOM;TG[Q@?E7x 7q!vEk@ WDv;"a"LGH .ZndG 'x^$5tYu=<:U"2;LD[HUVfMB\} `(=US-\CD/ʩ_C=>gyYtwd_X$؂ڤ)j=P!◁N;$08Z鯡Uн9?h5v5([iCo H"}วJzG*{QvN2 |1_N  E tmحtc2KMgЂ2~mR6z2 TxDr;6, ]@#&[gT;c}mOwo@.|ZWЭՔ[d2Q Mֽ螋&fi4)&27"NYAĭ1#pS?ڥ":.(x([k)MzȺ6btb9O:= fۿw> 1fE$vaQ#Q |Yl3'_Q[};6a3 qez=[v٪\nr,rDɨ5M:l$$cjz(oEb7Î2D l"lDžCgv& kGwb(=mm3)%Ak+++/ WTV-FIA)ue5Կ%yoσTXZZ::|oYVO.\xFZe8pXXX()8H8/Ԉ9 yރݴIﻣg\]MTjeq*ju%2saz"sBD: 8Mp9JQՊTDQ;_3 8:6Tq0 qx$N( ͤ4kkk ǩj:'¨Wnu2rR3_^Vރ;qFī3օa#"r#"r#"r#"r#"r#"r4&t FUFDlooV;+}_I$N1ZW,D4cAA4.Lc?&"#A2點=Lfm/^qҥTdjz?Mwx"DXZDy|۸ÕRcI333%0 /~&@I: s`fffI∈ ">c`/3._\γ&Ĉ1 ^^l6O(wu$Fĕ+W)6RCSSS7 SVSټt2;;{f_XXX($@~^paJDF<{8==}>yCV+*NA&hMZϓʉZV pRDFDd\.ߛ|FYIbqqqT*|177&[SSSf yB|wzKR 3N fl4?~fX|jz`zz~,--QJt'>fz~*ӎz^Qv<ܛ)'Yv?j$}azoLa)6?;Ye׼ cfÊnݺ8yϟqFU&vpԠ}u]y8T 487ϟ?* C/O3y1AfcL^ttfffJ{1U0l=^z~*rl+qP(I"s"zjV 8m[Ikkkv?1"7oN9Sq]w9i'q9uz!D9Iq\y^ ykAVPJ %w Ѫ+lF/79,rCz3d`AEnHe[ɟmfP4pfsjZ̉} @PxfYw]5Ǐ8l"p*Jggg(D$vj#x/ ҙ TJm.//d_9^fUjPJVEB^.#z}ܐnfffT*dYodhh4ǶW,)-+W ]WiFXnn^n~#$`z zFֈ y~Lȇ?7!E䚝֊T-IENDB`ukui-biometric-auth/images/Face/02.png0000644000175000017500000000572414064326115016431 0ustar fengfengPNG  IHDRbb IDATx]Mo~fHIW: ;8@n}z졇BO{/={ ) !@Xem$bqL"Ad_3$xgyg?d_d|}g™@M\`I1'x/n8($8+1#+}FZ \ gS=$ *NJ*tIGd_(/c,}sc/qfVq# Gr: I$CB GpܛtvOG!+k7؟}U!cJ@DGpuOCPI"Zq O؛v{1חg7啂r\N ORI ~\m8FH'B$(F冊׃_> <0i_2"-, )}79? S;FaWqZDkl3TrOVVIE [%!Ç~x͈HAFp bQ7B9>n*d0ÇdD$v/p?̹G\#s/1,l͕,h4ʝzBp<{iWՑܞ`706lllNMM剨9/G7 3wO˲93wo{l^{"$JO c,9wAիm6D4z~iaYDDh8RI=88J ߮mAؘD?3f9 +W,2LmcLm\[[#Bsee%5dFx<hmmm/tðDTjג̋D,Dض]|>"4C&!ĵFO:?6}`nZUJ!#0bm1kU)e3bkk9wcf9n!RڻF#_**sV5uwZ4+Wq--..ՑmDX,`0N,X__VX4WD#c0n|fdN3 >,155U^Z"a@DںZh6ׄ&c0 ꄳBjUUF# ttccccuBpL|iaYQ,0 c--Dȑ4mZ;o߾%0hZz%͈`_w9"'¶+ek`kҭug V5BKKK:ӊ"IQ׽-ι9/۶]:_gCDEX__O"뀶E!:Y_Tȶ$ڳ⒈@ǀ&Qǝ:40ЕFDErǀp8IDN1㏆Y4/Ngs> U r1~CDp]5U*4wu##B횦{'ۊ*4jԩ˲ kZ/3mT3f?"jE>Bq_NLQ⒈ "޾}aG9-JDβEiB80so/*߿_ޗ5JDFp8skp:0"WuDFc1[ZZJ8P :tNfr˵Zm>ʸD"xeȍMOLܭT*;+m;s]`U-VmgDT aTz3JMSžя7{-2;j^MbYqΝ{h?l HDә~'XU*t}9%aqv{usnR+l.y Dbuu5v+XuMAZvQ{Dh? PuBkI5,2ϟo'صi-3v"R+gv^t{|Z+Ͳ,09`bDPmӈp[q<'0d6@24tUÐTiZ횦 оseY !`Zm/JRnK✻Lf[G:gEDun䬗7t4j/`+mA<}ts^6 c3j%TQF$lC*s\VsTafгkm}P IRC?gڲMUaH n Y3$!m\׍|y"r,z=mm)?[ "!!S8Nle$NeY뺷 ɼҙξ4?alrp"zDD@VgHJzy8DHsL}D&뺟0777cnnn kȁس8u?mghEa&H-`&IB j:Dn^kt:~TE'}ҟ~ATtǹ8vm. !nJEء ; k'ha765eYFV3_'?y51h4ari<U<ʸjzp˲a󼙠/u]feu}s4w&}y`vuy9X(>ՈV*_uCdTt^ܽ{y8O%˲(V?tADRcO&/hH?-(/D"y w.9"/?Ύ3F@WGE)}}\Ԁ?&OxofIENDB`ukui-biometric-auth/images/Face/16.png0000644000175000017500000000743614064326115016440 0ustar fengfengPNG  IHDRbbIDATx]MlIjfl;*ц awClâH"p !!bnH{`…4$^,-"Zד7q=C~S=]g?TS]z^hfh+񘂈[,ݰ mlDy͉ D4CDSzC "b.yɓ3c&`Jڸw Dt&{a&:] D4TDDR#\+b[7\ `JI/-tF0)Kڍ)"heQMk6bEnWRǸ_j0$l0Ma̓?ό6)ɿD0 kx!c$qӔ4vCˈATא"*a҃ӦhcD}K bu(7K&v]X;;JF'X0Bk DPnʥKaiC˞ȖeޅG I&=dp\`w5@us!ˇLXǧhSO৙@)&}-ND4m=wd1]Q% # _|Kc*l:Y?Bc"Z3dDa:]=kq9 8>F%QּgЉ] n#i܏%>j*Bau3E ]#ήn}u&a'D0hKQ"IӴy&",-׈ ANG׈\ r|WX#gQ>ug(=rn/&3MCO"U`7GCDT5mm% 9[C &}/8_P1hh w|aU"J-u"( -\r/mkt|nd`Ht?zM0i`!xФ1ADw@ ~h$c׈ "68=!&(ko9F ]˙ &%Q"A 9r Z?np 5 h[4܉8O0؁&W\v_NBE{Фx*JRA`r rL~ Zpc;5hOP "6yր|?||>]4 ^TR^kxX!@fHR r!M8 9Tf e2HG iYCb&#6) d ~;e~5h.oCwY͢E[|> F}wQgoe",-0D R6_8mZ=hYhO`fZ0\;g877D,=rՎ` aR!8dha;m97dsH/S~]odDDX$H"MVvGFwm4j|07k֎@GskD A &!h?Jkd:-A wD3"$ M!A|-[;칙:X"$jf"lAQis4[-9$CG%w+4f=7'#p24 ط 2=.׵A!FIA1  diܖ+,1Yڙ( 2&rnľؖ&,h|{ԉXZZgW }X.&!g2a=0i|=UJ=rV[!pܹ'RN~@X.-- >5gn O /fEvyOWZg/5 V<+5ٖ vaʌgXv]'X_ޯ} c3< Ϟ1g8Ջ>&R痢ߨ 0}@xeU(s%+ CfG7 = jۥ=bS{Fm af[{ˮ FXV>4m_ V1dY+x6f65Ho;* k64u aOU þ? _ĀعccJ)jl]2xsն7k1Ȁz`Z,{N;Z8vIaa'TkxOTc#(\KD.%:eXFny)yP/Z/v][{ ثx3IPJ+S۫2?(AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA.NZѝ^<[+Ī*pXnILFqTjw𢎸/d] 7iэ x:/++OІIoW#c,C4nLsj,;,b83Ny59Zϴp*t`[060*1VJmͅϱ {,\6lLl `#+te{9j !^t4n@mוֹV;OTУate?J+S8X0qY-zWf$ l!|ןѵ OF{O:6}[.QZ<[aCs  ^68XogOXOj=T ]~R?l7j!ޱ>Ҋ.i؅[YSߕ.=-@py[)x3 Mc52]7}6{Hkg]KN!ZhW.:_!^ڇw[},,}x O>+иo:o]7~rm0'uU뾳Vcf. Db;' JA4ߢ39ROd^'2#)AQD "D% JA A|qY>ؼym=T[j=/jM春6QD6xz)8;R_ԁS'n`bǢ[XX!< ]g7D v;i<ᆯHD^`g"r?|4g IENDB`ukui-biometric-auth/images/Other/10.png0000644000175000017500000000353614064326115016652 0ustar fengfengPNG  IHDRbb%IDATx]=E}09);$NmRq*AئЎY];m_j]h^VWқ: "D䉈[_\H!"kIDD.l Z;o:)_ <;y``I.h1EGCDO&Œ[ITck9_siNڥW{jNJd@D4}xgR陈j![+4m~ 3J4Bf %Iz<ؗK>DL#o in l+!wdO:6l~JEۋ[mѶ)k񑎕 u1]HE4LD>Ǟ#VÝ}Gsi t ~v,GA%"*APJDT" DA%"*APJDT" D*i%_Iz_K.՟'RNVIm< m ߷h f4oT ;(X8HOȽ'` =PV["WKņsz`CbJ&>g_ik`:[%^VF3]quGsubbwcY^{BNڨH =9Ȭ$r8XJ)G|\UqL.9*Xp=VNlΓ\r*I.aşjZW$^[K.'foNt+](Ju%BSu߫D]TЋvpN-poի*J[JU{;J{[b^W6!X<$^dώ!,ܲk'/mR)~-lBB~^^w3]JjkGp[bik`~vom`\cA\6xOǶn+pKS&>`'Jv]pI'i)냛6ﯽKU^!/'Rxx;riʱюPDx')\ضp]~  DA%"*APJDT"`,EӠ39R_dFB%"*APJDT" D`8^*qC}:0dIDaK)Ly7)<`bǂXXIx9X@Dds\xx -vVCy@Dlௗ" `ܯAIENDB`ukui-biometric-auth/images/Other/07.png0000644000175000017500000000333214064326115016652 0ustar fengfengPNG  IHDRbbIDATx흽n[G^T"}r'p+vN~ TǍ)*iݤIi7)#g/I"'`{|w.C$"G"@D~e]bO%"I@DZ'| ^m󇑈ByJ=17OO[w|ojI)""w<~pRo;k'$m k| |]jO5_,""h7tEjD "D% JA (AQD^x^mZ*T@5B}BcaTJ3p@Z+huNBk9[ ŚxL @* @c0|tlJ}3\1Cavjs;Y(9l`|23Ok'}e} !ڃ@YPlYf” X& a .QK/CsSxM<2qb[{^ cm ě9lʦ3[UZrlgƦl'NJ QeX( Θ (!.5kcqOzPHkFT&Cjf!KDZ;RW19KE+uF jM7|V!ţzL_;"p8Kњ }-ڶ,Z1; Ni +4yx^vxĻԅ vlNZ˕7cVxg&R"һG)} D "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA3;cAN@C}.f^[^x~.{>m] Ed`[e&n7p}`Dys/9p6>~{jEEs iRχK>x-#{ax.}z3u P&X `?g܋""2|$mֳq2b e gYe?xf)-ccRX&hMzVlCMFoS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/Other/17.png0000644000175000017500000000121514064326115016651 0ustar fengfengPNG  IHDRbbTIDATx1nAoVAAN Bc: uLKkܤEimerGYA$QoS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/Other/03.png0000644000175000017500000000326614064326115016654 0ustar fengfengPNG  IHDRbb}IDATx흻r\E9{!Bs$";!II7@1JRE"HKU&t-i/jokjvWM\<DdOD^o9cDqҸ _VHD_vUn _s_8mn;J)Ddin|u(kȕR'~ID<=?ի7~pDDrW[.=4EhD‰' Nv0kʯs.TwmhrJ k{crNj 246 't}$f ~/Rf15)q}}h}߫a:3J4o֖rdAB&Tco>sOx`6hgY`x0˔*ˑf>bmbҘsO""_Alm= !tAGd)vÁp3gȈګ3%ҔЎ~p3ƶ[(S,QS 4˶>̹zѧ1Gr.I G}*= ZPإJ~&,nֵg]~>ʩT*.> GA`|Cj{:63!Fixm]9L~I+r|_*Ɣ_RX/>sg[}wyƶRJ3)%w[' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰'R˚&<pS|xG}TΦ̈ƾs&jj>+hc'9xL٢:k[Gd[tK,5λ-W5fTut`:L_:ހ_/-Ie..g~icvS/Y?--Kt/%CIڦAR٦eF`cʵmpCi5ײmPL`(m @Zu0m>05_WܿyrN0 iL[YPZK^T >Cc1 cL״{i+4Uߙvmu&C`xfK`g3A9cke0 8CXVʼn0NR52k(lmGNȴ/ 1:YMG5?4CjA[p-(vi͎6qxK]4P ֵ|UW5]of`iղ F vym?Ld^sE9򎀌3N]:(D?>u3\/gVFKI~7D "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQ"5W<̫Y=6Tׇna 3W#̣|$ջYR<\w+J`+${Z[1!Ygp&{3u=ck@9,;!\ fS lt= X<9>(gKj8GxߛvAѵVQmGsܳ܏YQ3q{`Y>gY~'U'́\b1^`9Z 3#Y5mɽvs {ܓMLY|Xoڳ${`'L1KX}ϋhW0|nDk3;[xߨ>6rV:ڽѿ=goS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/Other/11.png0000644000175000017500000000372414064326115016652 0ustar fengfengPNG  IHDRbbIDATx흿EƿYdC@e&9^b~7'N""HUE;m~׳ZIwW55sjԿQT`$"'"XD~.p-v},"'>↬7HD^azovIs>3͓ZVQxC-*w=1zD^aXHM^x0̵xgSYږi. CKBXGѨq(֓X߉}-0 EFh݆ #` kڵB` Xfb{Wޙ}&"2Svb*/2pSO_JB ۦ;jۛ&x^e =Uj!Dd"E)~D6* 2Q LT@d"D}rM]EA=}jNlk\4Ϥ6y&5D gbS;v}vvTF]*51:Ii7w2`kzwvR.gd KW) }7l&vF5g[,m[pTH\޵SforrۓݦmOsK{3Tahݲl ƠO ݜ11,9YӾ8;7>Iu]DkxޏCv:;caV) HP$}^[Xw\5) ~';<3LN fF}^Gk=N_1uw=Bb %SGi<{|lGp(m<:ȼ-āNf xLiGAXs븥w27Id什P) MSTUBA>I=b;iV:8gxnӷ͙W\pX9|r`2MPԈB|a NbkWvKjhx~}ov6@X*jP#3Mh)\m%.7ntO “Ge%R瘼ϰ5'x>4.n$T#2Q LT@d"DD&* 2Q LT@dZAGrR9ʿID&* 2Q LT@d"D'x~0P[j x@9f_9AK yl߯Bx;7EX!< ș A"rR7=;́6W;녈 ʣ wG"|btQwIDD么PaO%"g+I\Dj'| o\zOvE k}'7y4CcyZS az ~DccWS} Hrg ]"*@8QpD‰' N *ډ>}+1 wm5xk 5 t3Z,t0榭}g{X̓9df |0Ԩ=ا@KS Y&kwbjk}m R ;LD&(85S,R&\ϬQ(/u;QkXfآYPk&0+ZȚj{MkYl5*eb>#E ek cVLC=hSS>0߾rw~i33۵72;>(ղ,dAIڍˣTe9{\, J nk_h3FKc6 w2SxR

HDֈI"'|F"rqxc> |IENDB`ukui-biometric-auth/images/Other/01.png0000644000175000017500000000117314064326115016645 0ustar fengfengPNG  IHDRbbBIDATx1nQAAN Bc: uLKށkܤEimeC7`!"G'Y;$$IXjA$-~gFx~t}!i}z g% |7π >RIc`UNF7e֛w$!-HZ+PS59I8P˾tCO[ a"!L$0&DBH a6slܔNғfiW)_0&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBxߢ~;$Od/t&DBH a"!L$0`S;`UOmWpUo^4L_I#.AFj㮔 8`Vq6ؒ4-f:tǁ~{Rx˔'j$aIENDB`ukui-biometric-auth/images/Other/12.png0000644000175000017500000000337714064326115016657 0ustar fengfengPNG  IHDRbbIDATx흿nGƿ? MO4JWP&6RDUҺI-.q4{=z B2909VPn^ojP59W{%{Ư QVpPX58` g=5+sCSyI ! s6 + F FX7:{wB_WL#8>ywX/'kyY`5[suA ڮmY 0rDަ> o~ϲrL:oS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/Other/18.png0000644000175000017500000000121514064326115016652 0ustar fengfengPNG  IHDRbbTIDATx1nAoVAAN Bc: uLKkܤEimerGYA$QoS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/Other/09.png0000644000175000017500000000343614064326115016661 0ustar fengfengPNG  IHDRbbIDATx흽r7V$H3v'p+vN~ TǍ̤uZd&)*+`?Nx X,I ,5$@"LD~e]@%">| Zw#:))7 侳IDNɝϱ{=p6惟W~ID.<?ՁkxDDr74C"TpD‰' N (@8Qp;!IDrJ)F‰' =zKyWmj_*~^I7ԖBE7 "aiйƔD,djZj` 7ܜ;]8Bk(kPZU,Ba 1 ԧ&т86a6R?EuEDiJRl3ܔ"fWi3j@XV9 dAm6(Z|N덵-K^(hPqTcڔ5o@j6`pfT뇍T[JWmQwOj&)v Rbnn94TW~iޟ9m=ͩniu#s\u)J`B)Z`6[/)nOS0F "z |c:>F Gr0TŦ+.ֶ4=q^yMR Rh\u]ӱ]Kj\Ed`jx ~68a710rB:t}MM~  Dk:fjUn׹&sSC 4K}uD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpDMZxGRr_*e ҹJ&l GmG7.>ُk6!k~ڼwm]y4Mȶm7!]6)Ś&cmB M Q=Ρh9 UKH(W=oǃ 尥i4Cz6C,x5ȐOO&' ) PK`)9u^ 9ڋ-^߿~~PYB1]zIENDB`ukui-biometric-auth/images/Other/05.png0000644000175000017500000000330214064326115016645 0ustar fengfengPNG  IHDRbbIDATx흽nW%"p i ݤӦ@zq6@JZ7 S;hvER290g8 D@D,cDx8i\A pB0773=O'; +R~.":ԧ#G az~\D ~f:'zm")AQD "D% JAl{=*TF:-ۚmh FƵ`15PmWpQ=sm4x '8 opF9X:T3΁g6Smm-:vz 7 r8I4"l0K_Զ`Z!S"7Ӫ{0lrJ> j}Y時h`SC~{NmCxvC綷MS7祔D)ED$ԓ殨2Ma (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "D% JA (AQD "Ss\ǯ:Ϧ>>GU=nïk/4 ѥ_: dvs; 9iP3Z -lk3YىZΨNfjXt2Lq`OD >;y} >--" gY 'ja+9ry8su0H _ݒ>DL|3Y}ǟyעt0ϟkg NqXnTuw5 *s\o=:Օl5 j-]%ٌZ0|=kʻ Mr^3tW7G62ր,yo]-^YVuBq6h}bϞ5i gR P8Y@<-.=½q1[N7?ԦU0>(vxe%OpU#wQ ]Es6ߦ!',cҮ5BVOۧX3𗓭+21=C̨cCa"} {{{ƭ֕xk$A*D "D% JA (Ajk]]|Um?Tv[W#k-Mf1]D݋K)[ھ?*y8p&+. yeIDe}{߸ E'|#yF^C>1hIENDB`ukui-biometric-auth/images/Other/02.png0000644000175000017500000000311614064326115016645 0ustar fengfengPNG  IHDRbbIDATx흱nG="p Fi ݤӺ@zQ6@JZ7 SJDHM!("yp~`{{|;{$9W"K. ;*9["NW"rv÷KӖߍDq{If'^_o[^ 1oriJ$"G.rk4B12M)_&w~jT; */;.#T]"(@8QpD‰Qʥ^< [jgm.BεM=4WTJ@m 3 -01]1m D 1EWA0g p7#lf@[&tNtɵO1S羵h fzJmYb3a剃,\k%= %%P[ 3 6)raD~A/۠,-w.U /?6c4Aj:׺."}*:W:g9;lX Ȯv׸0hh-}gvϵ~@D4xE>|}:f zm/ >^ bږ#-:g|P\k P@i?'9 Da+Y0 ._vio[8#>g3ž*1F dH~SMcjFY/}V5ݞ*4{G_' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' N (@8QpD‰' Nv}4NR,஻ێrmFT/rY抠zG r\иXͨuR3Qm )#5WATʨ:@Pl5v[6(lSmaX^&l3ʆ%Wg!նC,^F'"2BY,j96%gdהT!/K߻45kF溺p ~Hdtγ[ЇWf 7(gVqk_ڞ`Ӗ\%`kgSoS`jM@C k=El%0&DBH a"!L$׍ p];I2\_M6DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH}c&DBH a"!L$0&DBH a"!L$0&DBH a"!L$0&DBH.7M'L' a"!L$0&DBH!5b~yqQ?U\֛W/LegQWJׅ90 6lϸp^lIC iqsݴX6ېy]HoD+9|IENDB`ukui-biometric-auth/images/CMakeLists.txt0000644000175000017500000000053614064326115017400 0ustar fengfengfile(GLOB images LIST_DIRECTORIES false *.png *.gif) file(GLOB children *) set(dirlist "") foreach(child ${children}) if(IS_DIRECTORY ${child}) list(APPEND dirlist ${child}) endif() endforeach() install(FILES ${images} DESTINATION ${UKUI_BIOMETRIC_DIR}/images) install(DIRECTORY ${dirlist} DESTINATION ${UKUI_BIOMETRIC_DIR}/images) ukui-biometric-auth/images/icon/0000755000175000017500000000000014064326115015564 5ustar fengfengukui-biometric-auth/images/icon/Face.png0000644000175000017500000000155214064326115017133 0ustar fengfengPNG  IHDRc1IDATH[Uqx]IcL#m؉kjCGǷUd]ӎPC8[_W#tRXsީ珳dR/0OwH{Ôbl)=l &P=^*!n dW~`US?k. GkF6*l_ij)(^0W!Lju\z؄Ǹl% 4ih菈yX"9w*ȋ;"GĊVEGѬlw4:Wʸʜ`86&M̜F.|)Kס*'X>ex#a1HHE8<p =X|ѕ[Ɯx~JZKWqH$vA5܂ΊM1.<(K/"7K&WJܕUKhw-2IK8-dTWqq^iQɬ#a?Ე;Z)VdMi z (tIENDB`ukui-biometric-auth/images/icon/Iris.png0000644000175000017500000000144314064326115017202 0ustar fengfengPNG  IHDRcIDATH[VU973)Y $ Hb!CR40MԆ`Ї|GQ胑7L缁P^0-p. 9{:>Jݢo~&^rکVKHV?#zNMzPzE:|I+@k<?:9\`zxn}o݈= < P I7   E 9SŜ$}/O:Kj{`*4~w} ؞oO9yx^+t2=uU{Eݜ<UnQOKmvJxzX-oY(E}!S՝5H&9|nh+ Y ̪z|[^$x Dv$fk3 m20!#5]1<> "SQO G"֢UPG&_b& U#fEF_XkE \_a-3?IENDB`ukui-biometric-auth/images/icon/Other.png0000644000175000017500000000037414064326115017357 0ustar fengfengPNG  IHDRcIDATH1J@oB",*fO,F3x;ku5[$V6a"? ucGNIENDB`ukui-biometric-auth/images/icon/FingerPrint.png0000644000175000017500000000152014064326115020517 0ustar fengfengPNG  IHDRcIDATH[VUj:L1^̲AJ232P"AEIA0PRtaʠQN==h>U|3~~>kgJI2\8sэI#fv{jocAQ7)%z88$dj3˺QqI6dHFd:U}sJ4o؋ D"$\'Ʌ~MIv&,zO&|u$ V # K|d~IHҝ$$y+ ` $ D} +f^~?.P3,VݘԕtnČ'ULLWw]X.-,Wrxg@Vx|'`FevAƝ\Fx%K#PWt[Sw:MXe4]Sz6ᱢ?l[+I&'INO2ߝdSK5cV ZSm(Ɋߘd_R \_I~J]IIR; et$?ɞ|dz~$s IC+r(6 Ao%~V'}"?ԕt1*7KRqOq:ы=UUq ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!  ! ,~H11-pt^?-qlp<(}2tĮrq˽?tx\! b{)OS@nFl)n$WӖK ;g ["P A}2]#hhv0B/ʄfN l D)Ŝ jn ba/bEFj%9.YB{%&\=_*ԡu2W2&&fZ3E]gDىm-G+/q%IŐr71KZIW 2K:sɁ"4=h# ,*el)"Sp5D=-ˁ'X{UG7#rr|'8rD]tԡ/`Nϑ fL6JK :ɹ"EA!2rsPp1S;jZ Q 5o#S UPG#" BBvvag O\>\=Pb3)S=4 Ky rHи`琭s 0Y\sAEh3EEAHm#\ɉ3k‚)c@Zܙq HT 6Q$g4< P ˫ΝCLi1#>X6킷Qe4ؐFc`7"yAaQʙ;u.&;`@h2k@F!NӣOAb6Н @Rhwa]cfc\ bP v)'PG-nY׆6lX-2] /`O# C>];HcPmܺNg?prHM!x`MTME]Zv4Dp zQDt! (n@GplfZT<GXc U5%hvh95Ñ%67Dzr!!d \P×_R d9&\jb'FcL a 6V}iǟy!(]څ&Ģ(D*P)BQ6VՔ@ăOeao)*r15\L<ÃF%USUe*lN:&첏pI 7D{e.! , ~I|~N-?ȍ˦-ҼI|̚ӑI7⎉rI߶lH@7bZ8"Ĝh Cv ( Ce!#F f8q sgN6̌$ 2\A0l;4Tغׯ`rU3`ʱD"bM"Y Z+xMUXX̸qĆKlG5\]l?P1`E_] Vlkb˞M[kKښmBj_w(πs͠: سk.:ۮNqaߘ Ϗ~(#`YO`={ HEu[yf\ġb6#RL2DS_: UYU(UHŒ! 8PÎ;R@#88# .v ygZV[DՑdGTR K&`cu%'H&` 2dx Y _Y]eA٥Er,s@ ǞS1 Ě 2! ,~~|I|ƍɕ|мʈёI|ۻI8܍lӮ& !OĈ&XA*"nBË $<(B_̚k D2l@;4TYAE.ܩfp!1Add:`B3\ʬ3E @TU ҪU;,= -@# t62 ^êH qc_H~eȎUgLE}E0)aa]2~\m$ #߷mWvVl@ՈRaRk2'Ն~]l1۾_ ҫ'O^5[³F4'"xЀ )t]C B Nlٖx G…!d 5t vxˆ'h…$^'@cV}:a`bE]U GvԏiA*tmCPT %@`Cw'xQg!&i8({|1Ŕg<2#B꣄-q/ R衍RBd*EA)! ,~+~+;~+Óǟİ+ѭϷ٘|שEuڈ|1N|-lH|ޑPYz?)ǰC0b&2* {I*104ăM,Br3f,9ܕNSe99رACWUׯVBf*bhz1rP`B!j)R (.aƆ jYiD0-&2$NRz!0È 6_{lDž'WYm/E3q4n+Հ 7͛w#yr Al*[.6y"hʎaUvƝߙE D a$daÇ@|W{Q6}k䒀>PKA(4^3 1Ðv‘fClyރNaTp•'Ԡ%\v_jTj8a{8f @Lq$XvZ=YmYT 8ڸ,O$ EDRk&k96(BuzA D&\Xv^vF$>J ڂ6@BQ첾v! ,&~~+ +~ҵ+DȨҩж+s;E;ӛ1|NֲՉ|: k@y .@|0 DP%ܸqaU,d&R\iB pmΦXTRĈ&L<(]t wpl\B!P(M~7^OB`F$| .w@(v'Ԡe t`~eZ8aQl`S( uP=Ԏ#UE>귒iC]J!EQE [a)m&Z-zՋFBRyH '~! ,9~1|N +|+ þƃɝͮ+Я׭uەؚE:""WLTOD3А#HL@1A0!/VL ?.! >rcG 8q^ );w`S3@6X 7x+=A-ADD1g̼Yag@‚Y  a|JRF,+*~^ZSWe-XX ^Hcۚ+WM p_vP8Wf_f@۷Ƌ۵-;fYEg@/%I}JWثlbjeѓ 1{$қ_@wߪKTy/6l :q FI}ҝw-U6XEÆ. B{ןhPQxM.a$/L3vMF $=ۄ @B! 5TiXVI'@`|0,^pY`UACr0O#HX#>{cLwbu3j $c6 !%y <गPN)eVR駠nY]B \zhY@L(isd]01od l Q $B%R(C!Ctt찾! ,K~~~:+DE;+~uuuƶɥ¸ ؅ۥEsШҐsE E:D.jǭD%{GϹq|2:xkף !JlQ#Gb/sG)jԜ#8fLR؊zx dNT:41ÐD`}Z䊉ED]6eE)zѽVg]Ä X<(f"c! "GN@m 5oF{C5C Ŋ`u J.۷_ְC X 7KNW]4:D`r)`_H*_‚-Wlv <f[uNܹ"эp_bv݁g 2 2 VHa㍧}Q*ҟt%}%6[ 쩰 20W P ldɐ !Ҧ{9Da"pqp*8 I s ׯFԀyTJ*VCaEn<hW߿~ k#UV-'~K7~9رa%T@iF. !|-MBc5lN.Bfh֐t*(bU+hvk_j;S:tA!_ji餈#1ӃOy4B&>}2I48EES楪ll:T%Š-1%ŅhN B pp!D(ӧ#j?n"`:t;^X6lǏXLy2 T9 n5ȭ)WE싩j୅+ DA t xqʚ|~Cݻyv:?A!lږ0𽁁y0ҫE̛n|rrv7tVqfq^{QD9Tha$<F؞{}ʝA՟!R`"ĈӌO=WBÎPT x |I8aC ABL2y 5D)%RVO6 \j(q6(h:8QBwWQ(UJ$M8h#aB 1ßv |g A )x!9lɥXB%fWf$nf9d1Š `hkqyR ! ,g~1|N++E+|DD~~;u;ˈ ;E:E̜ݳuѬ޸뤐;ηtC-:K/- 3@b,WH u@FBOZJH$rP%K r@EFH̱gg]AA h*k<[<EUFZsM(:"'bիabAC/<KÈK`` !ZϦ6[E{I *,^Z5 !E s mfY? l[lH lxէܾP޾ xq6\p -(  ȀhlMZxvY4\:CuxPUw_~U00.3`8@E XFJ`@jPȆF$ZXm ˜g~ԩ8?H# !y !9g xI|yg7#`S VX-%VTuE֖twv`v~eZMkibʚ 6Px* oJ[U! ,q~1|N+ +D:|s+u+sE̞Eǥœ͎ܠʹđ݅륗Dóu&j`}~a3 !Q= $!)aD?BAI,n̈蛪#F1AӃ r³'O9MAL)d #LCDU0VWZ+hk !ARE1*N!38ѐ+%PA؂ÈVq`ŖE@툶Vnnݻ3} 0 _0׭p0jVZnv.ԜrMQl^Zس3ؾ=lö!gݛ([‡_3[p.5w 0x Duym`i`Go5'(URLuUTT;F "`A}1`H‹!pŒ5pB8R<#3‹$ Xt_a6"xEYeaI(TIƤ!Tvᔓg_h"}ƝHg''EHH&c]UFg,aC'u! ,z~1|ND+ |suEEęžu+ɼѯө DԸۣݞsޮǭꜥ"Wh!"F@@11"ǎ BL@2E" JǐS=K6 JY @@v82$)U9l[HΜQSQ)R)lhp ;hR %UKˮzkX pǐ_l` e2h7У|*߿XbMrFag2۸sߎ")W̶B5Ԗ"d-h Es< Qn9sq k#4^w!*UV!ÁPTp]v \o-0ą'p 5ta5PС za!HŠJ^oa w*RSR)%B@F$QQ g`g 5E!!㑐'nXi$$o [SƓyŠ]XaJ$h ! ,~ +DsEs+D:ń›ѩϐuܓڐs߲݉1|N썮:ʞ;~uk$h|ʏWu[( ȱǏaTuoAD>) 4u#աyj+7"1s@ѳKi4ebJ:)#4%AB ;cװ{(M4O ].#'ǐ."Ŗ5mrq&u`iP* ѪzJ*b`MРlYh=Plٱ zL+VPvq:[vhPp XckaqAлX38E @TVa ]{6l r#:o zgB|ulh. /^l`ݽU>51oHki fPo Ȁ Qz]z Xp|]Y|aX`(.b+.b:z)geLEZT^}VX%ĕ LaPb"6d@w&J"% ! d`ly&bो*&(Ag 61 `0q5֑EF5B U^iiI6AkiXfy"QĨ/%+Jcig[ Vf";ukui-biometric-auth/images/FingerVein/0000755000175000017500000000000014064326115016670 5ustar fengfengukui-biometric-auth/images/FingerVein/08.png0000644000175000017500000000554114064326115017632 0ustar fengfengPNG  IHDRbb (IDATx]n>` bbk U"PK"ܮ߀ < 70oxDxHQPM@ ,EWi3=^>3sf3f`Q,џ*{(0U#+׼X+rJDE.2?V}E{ѓxV\b|_lMih˹v-6?ޗB])e5.$+>3ln7 whgDE-_[:Cu5y&fF) 0,T/ ZE|K O2ʞ3Up!Θ(֤Gk-o6|U -E xʥ&A ɿi"G35sQ4FF+DJTFh1I( #lɑx@~YݘyGsK?q!!221k&o*Ԋ0~|U&~ /4\`7Ljщ*9mPxZÍ>$b'YuIAݎ~0sԵb85ᵢ k}q~ J#(5o [2VbMGA,"$^-\ ?V@iVA_G,"TP#"zcNφJ.QAp"ع04Ձe#ibhm1*+%D̛D(4M@A L!=Yۍon D8 CiE {i.hm90*)+; D0Cre^V_<<1QVEk,uHDOm`5dLUdsZo$ g4(V Ya$:swu$5&yaf>b/{hx} XuF`q/Xɜ9 m&I`{̼' b " U窈J3V+r_"ckb }E>3Bm04Né)>St)>4&'1Sמya(""sx'B_90~vH e8QlEO[p  =\ht[|h2 2fw#=D^\u" Lj{ND/B5hǜn 3AC4BS0'<0sM(FWrޓ,3?EDU:}>ho6m]$bFD􄙟-.9s̼ יW`pCDXQ_k3o _xQ悐4g $QΙ"t%.8/h HPD#.ܬvδ\dOjY[#@4bMPmAZ9=dsp-_}aͽH৐QSEFH n`#mmG ӄIo.Ȏ\#UkKuA(6z_-An2GMDg8Uw2FjGpgX/WIENDB`ukui-biometric-auth/images/FingerVein/10.png0000644000175000017500000000555414064326115017627 0ustar fengfengPNG  IHDRbb 3IDATxKGg㉝ؙ0V"_AlmE b1orf!X|1EX#@D{JwDi΄ѱ҈0.9Qf="l1eU;J1ᲉS5A` e`! S~KB)e;SF!bC4?->&.HYY\ID 'VEt!s{HllQĚ : "k v/;NupOM1HLr:ժm\9TwKKZ4؟vhڒlWFYyݪ!"~7֛[ylmضh#}SC(m$Oa;ul:F"̯ m$b[D\cDl' PHDhěeD긹 UT)U l^PisS&qUmd=CTjkRq`a %>cׇ_~\4p]9}?H6/"oD:D%BUwY##K%_v/{x 'F xTUVk8* J!BU')`"&N Bޱ}xo^>< |L_fy!p ؋S]{U>DaQa$"lŸ \HĎYO b&Iz Q/Gw߳<>|t/~ o+8ւ8;v>k@WDB 0:MZtc á{g ~bn;,= "SGp E) =BWK$`$bqk9_Ue~<̚ `Sg{AwGؙ͢$PF:hvea[p5GBܕE#m z21h$$ 80toJh*AxYOIcjw8"L~ GDVqVY__ j< dz[#Aժ Z&#l,mYU;6 bj#Ep-|`jǛ <,{DS蚺I tqc==ǘ"h Azu1U}1D3h TWOUzGc0Й-ڪ+Hi<C~02-{~77,4qa(" ^aZZM$&L}"voƞiG0:W43W`?{ԛ5)5?ᕑpCzdzw6swC^TM7'gqo %$mDnBIKM޻>zB>U!-pqܾ UU;1Kb$ܣ7hiJY蛿ghSidžZe 7ZEH˲?j6BBEDf:#$o!'"{&L]?h":Wye>Fu& 4A e$̛4FlSm<`!e<9˘>aq ]>fz5qBg븣3Aq_tx-#MxT,̩xL,s$"ʩM1ʇT[Ms Ǎ3 ɞIENDB`ukui-biometric-auth/images/FingerVein/07.png0000644000175000017500000000553014064326115017627 0ustar fengfengPNG  IHDRbb IDATxo?6\PS[IqDԊHyhg8%4Ne*G\E"WJ \vxZ4PVyNAh9@ #!{fFɜFQCB#R4+k%v"2*7Mտu$Ddȸ^CyY**]]U TÐ (03]YQ'W 568\LkAtQI# ƅ9FZQ96Dd 76Zz¥2o@qez@A] J-@G]#fN9rVT;ZG_^;LT)ɚ7$]5wDAUD,Z|#w|DLĒ)=p@=޵k;| @@*C)D> w,AZsy{n .< ~GZQIUESc4 Kv} 'e'%b# /l)d) |@)I 3U5m4:I"i<%o*QG!~A#WA[FLh0Yo&aӕ}8l&)">]aLjvtms`33SΎ|%5#CsBքyaPp0$+l#yʏ U#VD 0XeCyXfUy_DFkQ2HsgHĞD eODvN=t;':Gl=ctׁ:|!sFc8oGrչ׫GU&"_ wTum"?{z#)@⼪wk"< -W= 0CU}<pcy$"n|SD^HmNM3Kӗp8Ed%"Jm$@DfڇI ;tꑐI:ywݕX#&KsZ:aa9s6DdKUhJz@FR5pGdHA|D,v"dVv~MQ;Bf5K+6iG&31I0Y7;_5U."["r7ɶMTmD vڣ 6}CXNZd&u5eӔ!)⢹f){͋-ˑPF>AzFoH'=UvMCQPFt X-J 5-K`q=@m&?%QzEZ0olyr:8ڱo!n4I#ZVA}ŝ3Im%bj4փ"MuD`o&d7OkmDk,&<C1F4eIȦl-ZtA 5W]D fv "b1um% g{>!>'1Exc;6 $ZCDXsEs"HɂA\uJ;ZClV=\A֣5Db. #ck+ZE9$nnX!ytqb*" Q°(H*H5Ml{tcKOC0xЊVaμuxdSjv{cvvWTmCSDJySMoQ3$넷44Q4McZ|I͹:NzO5"I{[ !$֥M^IxnRxm\d' c' և ;㼳$%ӈ57ӎ0 ! '!#tjn/C_ !m$¿oXp DABZEDf:w{d !DTݜ1Ipm Nk9N^$X[l2&"rs+q/Rz bk$M3udzLoLɢ9*a>ġmzN?0;+3{ FoK'GWjǣb3;A/sߖv!2oDU2F+jG85WE9UBqIENDB`ukui-biometric-auth/images/FingerVein/15.png0000644000175000017500000000540614064326115017630 0ustar fengfengPNG  IHDRbb IDATx]ϏGz#I%GyQ$ y.H!y/\8΁5W.q:q‼pl8ZG1^P_tvtq>=UWwE+b ;H^ D:S;#˵jwz -'~%Js*-ȦajFZUU ]0a*8 - &P.goєK̬s2Cu%j_\1Y.l4$Е E\W*g#'))PL򥚅X2x 4G˥5KK>R4 Wթf dHPWޚ)!ŌLQAB#RԕQ;j ZIGMeD:<2n_}D0kߊW`5vSULhk26ҁ*5#wN"M6L8lG'>AbZ[/"J&[+L >FR + A1>$b8 U&q4{P08@]#fIhPgS#Eq0]bz J&(9o 2v%i^w3''î/Wf!h|q"+jw[% "_۳U[>-Q2AD a2"+ |Zz0LDS5QseWMG H,T ]SYҭX[XD @"1 @rTۊ1a>j^Vw]Ckc"V5*=7e}S=EÛv2 D.Uթ\‡ [3iyD OGێaM5ޤcWke&;U"D)hFꈙE54)D" kRE"<戆.&D$HĞ=w&bE",zM PH7%DDU]sD(vcmtUv_o7WK FfgK[ap /n m{2Y5D#෋=Lepya9 !_j1R0Py,!c [ {A.7h ٦;&&әBfüDW6 V/+t9T6_WLk-|,t9~S rSw*UD$kmdClf]BAk<;sDGeL&%FFe*3ED c'؏ccvCшuC = Fe{^Mp3=V׋Q$7'](2}I3L36M]U?+="6ʒO>uC'$"ɇpgڏ,p W! ԶYD~Uz{Ys'f[wՆ,4AKeMh4MmjfηA[n}h֋th˞1ibzrg4kf_4tbcty_DpDV59f(^qD7p%bSp p LY"|06Gɤ*DTI`zxpw(/ifgq9DRΙm  _/\':$I$yigԽD%G~ GoO?)Pw 7g: Wq@LC 3_EWHD&uOE"Js^$xy~੺h'xw5}aI  HD$ 8BB{~ys"򼜦11$,"!O!!Ɠ 9/o! KEi"YʷW<x~ "ϊ. J+|8K)ɫ%*HJpD|ɖ<4 &S;$}0Ousq~F"ƒO}Db'li(JPC*)&ʕ2"ܗ{]ˉ/Ùp**qo4Qm\:& GnH@ۄr~OƳ,,1''w>;<\ۦ$~a-#ߜv3W֑{A:/2n ;ŠD5m4OiC} = oj Sm$Gp*yU]WQ׳B[e) o|G'33IH׈x)BZI+=[,+BBRsIKnh| EG>$7iǪ)Dh>ԡϑ "ϴsC7ݙ:"Npd9NF"Kyb7\ י!"B[?|?z91+ n?^H3d^y琜}oB U޿E䓬}Uo^(JY+B_;sH3^~uc<'g#u;dDz&!")FLu_ooΩ6Y>ܘǽ609!mSHn.20\ 2tP1ކg [Mǭw1eT;܂T?Wu+IENDB`ukui-biometric-auth/images/FingerVein/17.png0000644000175000017500000000521614064326115017631 0ustar fengfengPNG  IHDRbb UIDATx]MoI~ʎ? xp\i%{  C|k4w$go+IN,# ihѮl6^'zk힞vLUHzz1P y8P =c̝a'5:q1o./{c>̊pW%Ar!id8s0l{ԏG"-B-! sH[T cHnm2@PY%ߕ2Ck5T\ m9m)YndWn5 Q"׆tcNIyX*bU 0RJ;5aUk5pR Tܫ2#mP mWMxﭙ(Q $R/eq]Y)!$8dTAVƑ"aUGÐiߘ*j`D#mT(Uq>aIQt d}UEֆ T+iCJ+B 0|`<|^IWt8@]-fqhPeS#Uq0YWbr H! )9o m3ʿ9.4ED$ p,~"PD: UƘU_ ;CF}KiBh.1Z* $Dt7u& ^pwPB#] ʯX"1S#!칋3&D y KJ~[q^cH؋uq ][0<p1My:{2 R#BDz]q΄Ú4%TcXS7^>J$VJ#SK_a1ic"+ε!.&& ٩`"j'$K u2~04;?=@>$BrEU$H.\ 9OT%$pEW̧ܜ:._"%ao˳xPJ?ϸ:wny&#($I9ҤhB{ lw`{#,Ap ?P$ s'y\ [Q?}EФ _>m%%nO=!g\әEƘ3k &"BE8UˈX@>)xEojn!<sX dejpk$3cTS3|Q9MIJz55X"ޒwx DZ4Kw.Ͼ' &~Oϐ$L `U9#y1PC"H.!i*\!▕[J]⿍$YK Hy?C9\5O!k,`T #gg^K؂r&קgTpDKd5$ &c1.I.JMvZ1a_C5u_:aN¾"ioLri"D޻k2J?y"~=* ;6~ yM7/=QoHoo) 7|3ERo.Ipy~<$L&1o%$#;'ANii>-HY0>!'+N8 *uDȪ#8zY v,jKM=M}};DIsIENDB`ukui-biometric-auth/images/FingerVein/03.png0000644000175000017500000000561514064326115017627 0ustar fengfengPNG  IHDRbb TIDATxMlIvD*^m Xib@b N\م 8e%'G%!)9)FD(QZ1'vyrLϸ{ۛTꞚzxpIDW0PP/dZp5K_V\w ff+KyTszYU?Mݬsʮ ëVeW:粆tW 檪ӳy ÈqU 3S:cf\8T^QyU=rV4qSdLgbaG._^[~lOEDT2?$>{-Dz '`#ᙅm`:m в- O mQUVV}S9~ |ʊX'?OB &kCZ"$x8|pʸ 7A6!gCQ4}1uDfk^+<bKQ-e+gxxLya˥7Ed{+= :I&i=Q4aƊ;[2&io"}u+%vi!ࠅXzcH } 2$ߚtq pi^CZNO^$\A0Ss2!Ga?vdGv?բjJ4- cN;?Eط^[s;>!OLkw6D=#1k[}fؓjY6  )<.+!]*~LX_x-Amd/IUbSְmJPcV\U"o +C1gqA7 w]RU#,0 8a.+Պ -\o̹n SciU}qe _#XEhC Vza0«pfL\ ToI?v!"lâ*"Z3H,DDوvqCeL\ 6)Uh7ilb'J׊*6*UbKJMoЅ3G,LZule3QUe`DbB?:B 'V "L4o]Q%UR3䛈5BMi F*FN]-d2;C1"kjm>~1U}DB@DSx'(YS$L/a & 6b\Dn>yߧ\ޱQ"lX?C|>u3:-"+JB;v`DءUrko;uꑐÄN=y?E䣁D{Y:_av= ȶnirGz@F|9ǧHH$} I]B ∪Nµ[uҎ mY,E%gA@c&31I0č-EQ=]"-"Ņӣ6Q##HXM ֯B ;wZ"3G7[ES&FbZ-. (nȴ` bywN<J#N E=WhӼg]ptD#K %!9a7HDހ_ڰYe<q<j9Cgn]lMڠD-0hqLRD]G C a{E0_LIO7O{9q;xt%3fOF4eIȖȻiZA6|?0] HO5u%b3otw}?lQ6D$^y{ϪM4W!lKܨ\ FiGm0TЙ+ڪ+_{ԆCea$ʾVDs/ u,7ŮVDaiQԑs"wٞ #mB+jI9F'uW)UOl;ϘVWT̤ylRD˲kqU,y_Dza(S vlӂK:mν=ׁזw{FuRK"l^lιKL )uQ9kFKI¼,a;G)1nxHWsN#eM;jة! '!#ξojn?A(BH?/XpDԊd:݄~% iԟtݘEpmli~s9L'/ Q=H=G{kux20gx2>cKznL*  &%|gv㒪^jCb<].٭v :<.rU523ex.v!5țU2D6KC| d2O*G?H@IENDB`ukui-biometric-auth/images/FingerVein/04.png0000644000175000017500000000552214064326115017625 0ustar fengfengPNG  IHDRbb IDATxOlIe;qlbR,G6DD*(Qs$N R,YqB8 $\@ VDDIHH+V8wz5=RuTWWޫWU9`lnƴCAD_ʵz|9˵ |'c_;&exYNjB*>9t+{T|Ņ8f p_kqiT{IkUkM(E $[5TH/P_xo&GyN%TȨji Q[Y)  "2&""rHDȤ)MҴz!q2J7f.Xox ?2 `3q8vܙs[؆7&a/!@v}y BD&~>nXBb$#;5MgOsbIDD! I^'$v~CBw)wg5o>97z = joom}#zņ$Bi>6Ykw%%"ED?l¡>"n5bHcքqIkG`3??~ :Uk_ص" :v4K1zBx `8aI!=s{@IZcY68k="[2l 3yᵞְ#"cz0TPǁx9Lk|D-A;͗% ڋ8Is̓F ’ck"p놄W&!ۉ%0v9I 2R[}xI=a= qZ&-/ ۢYݲ:26s o8F:px-v}T='"2{eqFAXxZDqR,a`M5"bF"=WR"s,DV("bJT9#t|s TTCp"l;*-h<]pY*դl EaFa($0Ў ܮ?+4IDgpNA=œV"lEL(2DLM&Ɔ&4%f%gXoiѨc: loI694(^;&5?9֨m#bHj!nƎ={=6"9網^dii +D̊x\z~IQ91iPYR]Bhwkd&AqG|XT9^Cpp&2"%=! f* hbׄtȨEjW#oG΋JLSp/c y"-e^4W4"Lt3| ZyPFtXJ 5-gՒss^a'K"7a7 &i3G1h$g2L.i:T"qYHhn<''./G 6t?bEL]7~pâ1npkA$z[|v9MQж 4ι]ܖ "\"^mxfP\xh*;Ip{o͖D :l%CD~6\}QD>Fs"0@%F>\J;C„|Z\Aƣ1D(B.3#fk*E: n!-mJkm5EAfEX' %.Yih k?ZH"ԙN 1!G=uaiuEʿn/PԹ{TD.\&G 5Mox_;;p xc#} iz[ !$B祻&靻SB7W&YC[ o-[Wj?DÆp5G4"lÌC2>& i vS{p{ b VD"+T -$QDî$._AWv?֝4W@fde>.OZ cܝ~x ^ 9wȲeoG%7g oɲTнPY/cjG?jPkDh \՟>P X5,2>0ϥrs?ƫ!(r,qu`Ye'@1lIENDB`ukui-biometric-auth/images/FingerVein/13.png0000644000175000017500000000532514064326115017626 0ustar fengfengPNG  IHDRbb IDATx]o\WDZK ((@qB">l mpݱybUňHlUQC'rIjɯ{޼7s']z~%+b7  $/XD%uz#", z&"A^kArU[$'MXՂZe#[7?nWC ]0c*(]Z&ZSޮoQ ̼K2CukԾ3o#[5\ }بIk9WNgcHZ))V_L劅X0xG+u6a[U}ᥨA[RV"ު@:WM|L y.ȨjʉЦ$x[GG[WLoL+ͭb!tCZ>@ў;ZQ%&CM'" tUE }+ o":L6xdjE 3z'qzH@G? tZ9&@*ӝRd鎿sQ LHyvr8 AH#^Q;#}7/|^DЙ01{+%F0ĨĄ&"j,vcdCQg#2ӮFtt1VVu Ad"NDxh} L4;ptv1|/"m75.D][0BܢM;M1HƬdUuTk:߄-5iytKZh#mmXٛvV|U5BD>0v;A\N>4GL-HDPF"vN!BDxa戆6khh#S6oV1Mh#Ku  m$:u #"3.j}_:"]s K$/50Vv@Pewqɗ ]D ؀l4k~qsO^LoϪ #o8xJY$U# AF^wO(v5dpRN"Lgfz}D o8,!?DҮѵY[<뚉{Ԟ%į3}*R1r*=/]a>f*`Z}dCln_BWztxpw([2ԈBo\8*"rH,pxL;18׎oJMM}S` _D.^Q7--DX^-Ո5A/BMJdjǰ&M8$+dY3t(KB}'$"{pgڏ,p WNwn*[,". H `@ABX2t58Y2n\߾HFx o޿m I '$㜫w"$T"*$4dID#௿30c{Oؼ?Hxw5}%ÒWK~ax lʒ?pG(doG,S"򸄚Fb,"H qI|O"F6! OjYIG"2Q)ESH>g% rD #4?6q\]@nϑ_$ k~)>{4 >-h#GyA,Wp A7l d#! N5k9C}_;$ Wk+ۑgk%Œiwx_< Ink(}9}!!!/qgֆ &13a'#KoO̱g䟳D2\Ax {PャHv81H^pD% Q>MU]ò2Wz2D\V㮈|Z "Huw 91]ۏDNȸ*nHك)}b^{$j&C6)"A'k=i$C^gQr|&"h:+G'njcOVQD(I~VI*D]uAv?t}^SmSQ+I! tAgڦԣbd{@#E}z^2q ړL M&D7qx7imQy4v%;$mD Ƙ*BIzy}EzR60Hȷ!D-$o.R]ě vBK#b%$#9<̙7{nhgΜ9ߙ33gf<$0I6c޾ "3@H _2ƼX9匷/"pAZ3?r)U\I "6lƴV\@db\Bg,ش zhF  "%\Jfe 8LFrhKy,[=Y!"sz2W@/(jMz)|:[>=t{邅qXZje PtӮ8)JRVI7JVE$$ hy&S*EadBD Ki,‰PSPIRn* o#!Aƥ+/+H|47'ʫ"$!c)^ftٓ;XQ$ ^Jq{Da*/t ("P\_cmHv!*BD,K< 8_fD Druԕb$-HԢ\8$:AJ0"Q5oiE/>ARÒ?Sep7Cwcm,A*ADua447"9 \YME5&o"ʌy? /7e&1 Yݍ1巈,"1h䑦D8.&)Dc%,);!a>=>}n81AfEk(t0W׀)cV)-O5灥8$CX"U/R3ag&֧7j9wصjƘ<~ 獺{u$j(SQG"QyD8:2PG"$HĊv&b/Dh-@^#YyvD$z^_+jGbыž\/u0n-wwmc-".ឆ`ȅpȻ$Å i.Y#I14o: UW.qa2"sOFpmGG$}7>V+爈+dH^L}l ~ 40pH𨈸[ƘNʂa"z'v ྊI7 l_XD>|Konցb[}G%{8 [^~q-1}1 "F 懡D|FS菽&YF:OuI~?<{X^T~ F*{ hyiҖwDOs1w-™qTqkrbbk!x7_&N$)'5aÞOhi'',irm;RV%,> >'MU&&Qk-vN|]%Χu U$ُ5B\SE$.MB״ɖ~6pxRG 6U;^:֔k|%-d%I+@XaySs$\1lfH,{hsfY+](KfD$xQ& YVVTnNr3cV =nS\Ƙ=>ZC+KV䈻:踾hTraH+GVGL҆1T $;rSEwCC3IU%RbPǢ;-#B_OIpJfƘ;XMc̍bU|c7KW'fOjqhADZ^7lccf+#*Epݿf29iU%&c̎~9] Կ%"'uXKTD'Տ\=#"'h*C y\=5Wj!B}Pzz,k` VyTGeńZ}ks}qJpJܿYQE"nQԶ;7k<*G·VQI"ԙ:a=Z׉ǁJ~qPco4uhz4ww4N4Mv;ǀOsou%Ν$nDlB*IK; Df!":f hɽ0]F1"rI wsTE$6{3mAr=YR9" 7`#6K/Պ*6MlXަTĺulM!w !'"$la]-B6ʜѷeCws9mS #s%OYsBSCDf{Yz9!]4/v } U'[ezڐW,_in`6?#^0s\D\{\w ǿڣ&c̏Mb2#՚3GFQIENDB`ukui-biometric-auth/images/FingerVein/06.png0000644000175000017500000000543314064326115017630 0ustar fengfengPNG  IHDRbb IDATx]nf;1'!K}'`߀70oyVq- 1 cW.LM{f7ϑ%ӷt΂ݖ)>!YqG~ ''NC$f^ky02b?ߙ `AHI#jk?pN#bYi"$|k2{8m9";BDHŸ2Ksx IDfskLi'MDl>\sGD>(O!7<Š'4KA~7]8'.K8Ӟ]#]6e?p_yGDg4.043TXI# 3_i֠y%1MސjՈDhI}%$>k2FhFaؤr`n<^\Tb?ag5pB&7pN˦e1%o"8HPwdgkं ̼`o%?"\Cg$ȘeYD%L3|EDۙDU:pHGI!dWy Y8r9mDX$7 Y;/**"舣Y8?곾A*DI9%16U.,0 BD4B33/ZV:\QF7od+<3sГ2S̼[Ee%j q{'U$'@0| BLw3-\PA 36/\[w."nрbϞW8=z%f޶Sh+oED\ ҕ]WyK8@(&B ݌ 6\͟p\8`n ~q[ 1SD `#^8 @D{Zk{[,mm}y׳kZ$ӥ e*,v#5.Z]Q5g}27Cྥטo4M״K.νk%X6"z{[dž yI7iBJ}n8g D\77o= R{[^]DR-\FxH[5`qZC泯IC#Ԯn#Nx 3fh!!A[/!Z]  B'_A\}xx gΚH 7'cmXh#(82ZV%~4S3y) L@Nedײ%βJȻU]κ6dWe _Ɂ~wȣUr+2{\k9Kq \ck^NUJ~p"s-EjlIENDB`ukui-biometric-auth/images/FingerVein/01.png0000644000175000017500000000475414064326115017630 0ustar fengfengPNG  IHDRbb IDATxj% / !#acg.$y C5r%3_Hp?O_D~oBUo۶4/q{c.x$"#BU?ڗ'STDT/;mhmmr|oAUÑL<ľ<_ {f+@Ucg-`cqE|~/ UwI$#K1{8Ur_8O> 7?@}#"lv+}La$Sǵ!sG9p*""?7d1Ш0uO&!CQ-\7Mٟ&??7pG˦h)$-ڵD $B\]pF3IBv<4%w&I02۳ =:t %uTS) ozT4!:"s% 8 Q0WIm@D`7TĖ_G@+>%&xU*ICc`쭨RӅ9Ahm,m%ꎪ~w=VE}ߞjq5mAtaީXasj?(ԒyK|(Wh~~ۊb׮schD0I:t5J9zZ&~>iV#1g\!,l j'ԆuGZ ڌᕍ!ڨM" EΦ 'jD:4EsKdTS0$I۸9dbLsTL"FT'&LdԬ387|m&b؞ U*bd`1rRq ?$a s[Uu ' TZ7me!dUm\ږWca fݖBဿ1\)YyvcDY.=_X}kbt۴6*HG~EE"Dh"RAXIt񽄥sH&C2Sȹ$VF5u1EESDL oT~NyC%"]-`UKH;Bzلu<ת2>?H+-` D03Nq譪V'P3b v}ehl9A`2{"bvTuA*xti%",9`Zǩ ஭}=IazlE _U."/l/ |md0Fs8"Tmh"y¹clR|Խ{U=m^Sֈ! f M sDZUdRuU}AV+jRU"r$)'鲙y8"Uu=?*%h C\9WeՒGB :)IG&S1I0 TBT\DE3YUTvr\Q JV.jBVq.L^MhD5HJ^qaEʲ,^ #)%ڼԢyg=~ӪIZHyIP5W㢨mC{LI"Ƭ fyi*se>qoS[$#t6zj`&WIKBD0kTGD%|gBC .ĚHXo~d<(Z_ (qK:x炘Gi~G "Eּ P]uI4_.ǴѪf1*WӢp{ŠfV/J & I}Qu;UEu dKB6N]uJ:!|P>W`rq|H}4rjff_Hs/xi "qsҲHK2K3m!(2˳P_HED3h u*EZxN];>ccc6Wa*VEn8_s,̞W1`ۺ2$IťiLƮ_Z7c֐YKj:.nej{d :͑D=$!.jn!aSHDX!LX.t{AB""/B 3ml)8I|]Ksm\1i޼XBt | 8Gmt& [y1#xyYg_k‘mvRdz7r~̟OlHUhCakzP6eX5ӣ샧zd qN Nc}87x88ξ~Wvĸ=[M"NT-y٘?ѹ&LIENDB`ukui-biometric-auth/images/FingerVein/12.png0000644000175000017500000000545414064326115017630 0ustar fengfengPNG  IHDRbb IDATxoG?c;v9U6rQVXD7QxqUZxppyEB ]P\Z @Z IĮӇ9swvޛcMhv=9gf5xs&:aj95z4liMc̻_c>$N.w9Y53HTƢ6nKeuż+-j:笉m@KޅbEd{qEUpF]K"-ꎖ9:oѫEDdEwV Х Ez]ʹ6eVNuZk^S>?Jxqhh+J+ֆm"r7TZ*v hV&BIo>L9(FF!DdPHIʡ1t" 2"Ϳt$8d\By#BOk1-= D쐱^n;Z1L"ֽ*$l$qXXN|")m/4a[Ca B3FTNDp*bћD4$|r7 I8nSߠ#ȏbu9I,w`(9IwC}Iz J#!dy*c^hw ED] m$+=1ʈESfdzz1coD^r{( w"Ć0j9^j!L"7Q[eeG)?5o;o"tM\0@J~=lҡco;XȥƘD->bß;uhG "XR6w+b}4'n|-D]-b _c],c ,豰a e Hƴ$YUj/IsaXF#cXś4v3Wvؕcud=yj}ȢD4C EV"oT7YQE"sDCм_4TDrÞJ1J">jEW /T?W/yrD=#Bmb_.mʮ*ɓվ_,QVZ[0w?#"}Ȑ- ;"Go.֏4^w@C"^HzrGB:%[yLnK=ޑV Yqd?DH2*JkVfZQCc] "TiP>:~@'{IZwG-~Y_%hj:>Jѐ "rp)=v^Z3Z 9k. wI[ChiAQ~.)1!"Ƙ"B`=zR}GZikq)$z?)"ڹ4љ?}axRDAI'Q|"z<~Uԟ:BB,֥m1ZpustV~p{4 {^yG=`5&RH: lN>ܥ]o4Hs:ܧBEp}q, 訧 TiiGO#tx6݋`[ C= GONs,4Tn >?Lc^[Kh9azV@N(?qCvu K>vf-גwJ!-~ we$*s8`q? OO/ l cv?evY/}hYbt7t/OƘ{{$Fz~ۯ%鏞`ˍP{*T!"$]c̞1枺$UǁȬ+RA>Ps^pDQV"vݤ`9/u5yADktG$K"r4DOvsAw4]U:JC1>6pV]A:6Tz'e]3D= sq}خ]P8%N°[$#DukG#BG*JIܛ@'55ҘZ agR~qP4V< aۀ^$Y),-"t3!R&h5Rǁ/kpo:ANz$ ;#CH)yi"=w} $*8g hi;[&17Edl-<[ؠ ?oힴf&r;}JR:"H H=D"DS,r&N )ujN!{ t N;BOD;c`%'3x dȧ,:#QPs=kS #~u u7H>z1u.35rNc?/1PvȺ u]wS?X.Rlc~؉e$_H[CoHZ+YG4 B&cXSGjEP㚫ؗp>83CY _IENDB`ukui-biometric-auth/images/FingerVein/14.png0000644000175000017500000000542014064326115017623 0ustar fengfengPNG  IHDRbb IDATxOh]Y?'MҴ:6AA]H  iHMw.܈D7*IfBqKNi-c$Nr{?==w0ŰꜻTPs<0G95[j6Ծ[t :usV^K2<tzΊȢQҦa,jA+;Ҷ l>_v flQ]u&-}`Ed߲1Ϊ0J~(ї)һF8gcOMZ#"+RS.꾦B􈫴xLھ%*NĬIH@WKqR^*l!"B !72rJAH:QC%!{3lNZ!v)Q9 IB@UeD82dܨ ꈐ}-f\e@ҽ}W5DHE]ZP@hפ;Z{Q%&CL I8G'>4]IQ QUDPXaXcDщdu! S+bLѕ8 ef@hG@-G??QWd ԭ2ޑ)EqH᯴%鵃(`"F$kސӶƾ(EDG aK 4!N8bp=4/yRJ'BƜFA 90MFS6QKe9c/:UX &Ȍ^/i,XwJIs+#LD!G "xR6(W*bC}쓫#"z^E{c"V5z5[5`9`Ae۩9U`)1kDllNjmTT<^=u@tHM:w4Ș]:vjs=BXol[:Q6HDՙF"戆6:&D%HVTv&bF",N@Yh#vSW"F,\_o+ZGb KJ]:"T}]%i/[::%`)Xmmm9 ]}g!mrY4nMdr淳r2aEz%#"0ިܗ>䅭~>"Bj=ޗ5d](`~>d93+}wkQWzc] 6* usV}o`^`3cK,[ zڀǧTn7ViƒI\ۗDU xbۖ/LKrHww^[2%2J]p%ѕ>XCB_ CǓ}q` nQ rU_{Oι_ʮgs3:vW^5bК~HP)&ݹdjG/n4 9 ͬq beP_Km(DT9wID/tA!iWCpu7mBvt@/W{0ZJqךz22䩦!˜D H+tS^5h*W.9?`զ&I/t%LAސ7>o颱KM(sEew׀"2fJD&E䈈41)TztKDG4`0Ot/o~7Ok|Բ=YC}>sUzi=D&BDNhGU?~ |Oπ?n҃ صv5wm}RI`>߲dXR,!ap$ B~ ~A~Ak#'!K@VL+ MLG"!qv)eImř#W*mP<ۧ5^e97 "B ic,39HT/bv'x`;bpmxB^S? xHgn;I1fs(L%-^i,߁/نݪ/*vೂ &`8aA yM}5cKjxNNK11|817,8xxCoUT?7HԓVQj^Sxϒ&+^>Gcy߳mgm;Fb÷)H:[uuO#~vWg˱g{PX^CT7+ A&AYm!n/"rx9!>[ιKLHsNa7q>IW:R%G6rAأqD(sQ+Isn$)3=U`R*G=O:úޅWF#2a}d|opk ojPud'OƱo,nǒci$杶H󼃟6ze-⻱G'iV3~^;n W#t]>0#PNk%[CN_Mg!#tpL{xB3~[EH8ι'{i%~qu4F >;qp!D%W;m>'Ed`!9*σG:c»{'oWgs_e$t1Ar5ە|C9: ӔƮaKJi*뎾^P=zU?J[Z{]Y. InH[OWS)Ab9#")AȗNo+#m^q.fPD#Ֆ3C /Q$_ϡIENDB`ukui-biometric-auth/images/FingerVein/18.png0000644000175000017500000000516214064326115017632 0ustar fengfengPNG  IHDRbb 9IDATx]MhdYn:Ɍ08B \3E{SRDq 'DوAg"Ղ QJ*{%I[[UޫT= A9 1J $C88#?5=r%Ccy^ArM$/I#-t: mPx" ۑ4X}?)!; m+'G.+DV)]ר s=ffoGe $0h(Asu!8AA\⩘V{5'b]%a,8Z)xw9Ž$|å^fZkR"B׆ 󂶏VD'DjW+b O3|a 0> 0BQG@j5uƻ0RdY_kٹ(`%FH缁t"O \Os'é f)H\I8bu:Wc7C[./Q Ap"h0zUKib]bBT;J1D84l`5tPzb] oXcS5 F "bsfL6D3 y Ka[qAcBMq{D][Pd06B-|;Ճ]4<pږɘ5"6NΔj s*lV90&@5?!l=x]WcwFc G hCk6biE"&C M&"4HkLDht&9D_4tD8s7u]DX&t^ .#›ۊ!M#%cmtv"C=mg2:!`(v<3c߶# ''0xpD;S68}:s@}"_1e]< –o^!a%¥J!'T"@}3`: tw7oY47}Z ^c̪*}NׂJ{Ea)z_ZJHD0[r5nߧ Vܱ͵%`ŻkKG'X}T\ndZ#Jmddv]psX*"rH8~)avm%bO')<Dڲ'q,31s hƛ>Dc>0ƼpH,R#<{|gLM}u~`yF ՛ 5لG'rGLC"fy`vxpw(7B5Iuv"S̶ {eՌ1^ǽD[pgi11]˱;t2 jE^1#y7z:"V$h%2t&RRZIՊ~`EZ)8NidD45 ^s"Ffd;u \D@k^O CxV!$=Uk}Bnxm4֞`v==SyW袈i[G+nC :-4"vTzz'%11k$oCKJ?%)^S $Dzws+U s e\_ _o>I^x.չ+c̋@Y. $C/"ġ#'e'~ ` ?#\?% j|\{WpĪUضy" ` k; M& -$ / ϽP!`߁WsZ*ɕ5'h$o#Uy5&:yn<" 9 $gƘee[v`'avf$y o+xE}*"f i S[< {d#H ޿DKW+?b{.1_!hyFʌ)Ky)[a>5E""F(~iX!5"4֐Nj*AMM8Amtk, L޵cwJ#1fF.1r5YE"tkuD(psCXc`rp2)#=g>QTAD0I/L&s ;&?V7G?AQÐ>XRJ3p%H@1C{Cs"8`ɰiIv̛I oE3OAeaXD0i$""N̖b[p4Y·Gg|z@DciL%"yMD6|Ds -W ? M53q< }S@"3N0nd !Hg&KZӺx#-|MX2@Nޙt[ a W-Sr!a֐1kРCJ1b=z$ 1[EHH#!C94. |HqOW5XHց5\".@ ڼuS"i{ss"ڒ8D1F5! ]yɨld7O*9a6F8(f#"t$6'р_{ ̼ADz3]%UhW&cSpy?p NԿ5Q!v{VcېVND\˟pmE4DHEZC"-HjYfv#me"d^[lA$i;#ԕ$=%ؕX !o\iRwҚ͌gF fCUodpᆻ?>#aNpv;%[pDrq"<<.j2,kv,bҎFJĔ&A ǡpK`ҜƂ"zH0SM}\,CB}С墸1Cdݗ˯'Ď~%7lpߞބ:ӹRd E*#N*M: qhկị̌QNUA>}}9h$+IENDB`ukui-biometric-auth/images/FingerVein/05.png0000644000175000017500000000545214064326115017630 0ustar fengfengPNG  IHDRbb IDATxnIcO+Yul,A%1>Z&+qO%7(yP$(Z╃v{Sg=qt7TW:U#8is5`ܱguCs,|GDVqV_~ yeKyVKz]Ul%he>v9M슻y }B|KVax`qk@-|`n꥚b]7#*Qf^͏5Q*G:E=+*-t'{͚ +HŕR#ݭ®OuRPIݻC&|> NO 7Lmm"'S{b/7y+wmUE; SDN |ƹC OT"k!yj-[Afo m5ljzAQ2!6s9O,5 0'#m? $;%@v~tρ7K_WIp" 533Gœ#cy]n֓')VaC[!SOJ Z8RN2I5#".Mo±;@%s]TDVKL'"t HAAئcj(#cƅ7/KNolyJp{G).hdCU΅Ө""iED#P<5@3ܙZ61wDĹD:F"pt{Oh#m$7P#uL PHǁ9$q`TSL98shwj"Z"̼1So|YEgv[Q'cFbKؒM7E䑪>atxXt.%% ^a'ΨWXUW wU3頍 "bgZlEakOs3'/6,OP"6t6gRSBF"My"ҳX-zPg͝uqk' 1Dذ4 ~{b^SYB|Ip:af 2b;uꑐN=yE_DFMN;6M'#b$QMV\UȈsN~uxAyIݙF ☪NµMj'"!a70Z[mR똨TLa wMG 5ȎCqzf*jbD gr$Gߐ<R:K_/LjJH ָ.ZZ k#[bR-".t -e4r7zCQ0aV`( &8xV03w} јبIDHl [Ej=nly4r:8ڳo!nTI#FA{["JĂ ŜjoԈ3qqD`o&[kqFFQYq3WK N}lmdNS/l MCU("o v "b`1ϵM%b+o t}B<'ΨmJ4 !;vUcpNPW' U1D *.,o<C!vq0u5pg_S("̸'qIcFaB=Ңh"kd#Dys6&VȣU o6>̪zENJKgQUs&^fꏿCnWb:Qi^nQr`<37eqH#0UIENDB`ukui-biometric-auth/images/FingerVein/02.png0000644000175000017500000000535714064326115017631 0ustar fengfengPNG  IHDRbb IDATxn7flhWJ7Xr>AoHy\D"m0ʐ11cN.tMg<]JU=WT9U5BU|f `bȳli, V\~f=g `v#-p>2rd@艈-zA9ݳ.pWD/TL JSc2pfg{',aoqd?7/{m`KDJUg@4eg3#W/F\!(jX~G8.|H<]ța7V_4:JD}x]D ribO_q{L{#ěy8o G_HHx"r%@*<6OZ3 gE`+$/6[>PG$' /ߒ ;vq$@Mt#k ?_Z}^7(~U}SO0؈zBΘ9UR0-}B@&I8$A I~ȠۍP}G&\ l*U4\NU`ϱ*%"*|'0>$y*Ţ}TEF-Dd\D˾oʏI*#?֖u4 [`];lUu6'SE%D ]f*=Rd,TH1adpQ:Db{;1lẠ֠*4= Foa -$&i.$}ul([#}MÓ\VFuW ig,F^TZ1Mq^ꇪzᳯp-=#"?JچY\au * k+|j/4Yiiہܳʁo2Oe OUѯO0OlW)i9IQ>{HZ3.Nbԉ0=s*R--C#B150T9@NL]+ "e ;=a|YjWCH0sbiWӊȡӠ6L"zO3oVp䤻}lRZADqmODKUm":kh FL#'pԓ lC:8PۛT-û[UIx4"BX6B,sjGӈr`dXqQ&ED粌^KPټwG#ܪ=DxQ4M$%&ớux`KC8h"M<h"ѧ4M$"ĩ95KԘF82pNU#Eપ^|'9cFvQէ Dj= ,${Uh[D䱪n̟7p!ұ 0pwD0ӟжV'yA.sb̉ vuel9A`p6ZU<~sXUՁ b!Df JDmr@ 瓚ř}Ӫ50$/m}[ǷNcΕ z/2|6_oD/fGĢۚ!ṵ5gIj{[CB̨e`a۱BҨ{BuHUD/0EFDj̼$DA#U= Ѫ/T> ?m\wFHℾ|@7EgXQٴpaLQ9)p ,j<)K]8!&d&0 м7f*?*U."G"%8=_rU}9 ! w.(EfWf4H 8o.YZ#т̋x%*qhBm>FZ0/W^ydyc$4Y^EjhyDF &Vu% @/Y8+C><Ђ E&n\DG w?d5sKabѸfn$;_Iǣwik |#Cp55WMDTD0 /xcZfe V"YQ8s=Ƶ flRj坛c~h!dI\8\ǙFiG4Dt֊! Gh0ڇ. #eQaν.^c0x!.niQHIOu!,CtDBЊ(0g^eZ_o~taשivEh 'VbxZQUĊOE$ 35CqZΗt՜{7ҧazjKM2<8!S]^5bYC[˸l9ɢD}N#RHk8!pMҐ`m{/EH j!1nNXu{@B""N/B Cئ #$~"3j!ε%oQ B:|g:& o[D1#xy0g6-7|c_,cxN@+;Tkz°wn0YoW3fGoUV[M?hv m0'q+κ~O {vr5ȗ8U;3~vl86']`df$ IENDB`ukui-biometric-auth/images/FingerVein/16.png0000644000175000017500000000535514064326115017634 0ustar fengfengPNG  IHDRbb IDATx]n\IN۱ 0CD@@q&Dl'x%5@$$bH6Hh h`LJE{nu{O;TNWyv~'3$]]1p(> FNWzAGD}n8 tzyhIkRBs8EڶՏۡ]0ck< %g浚vۓmE] \aJ-e kkԑĹ3o9[Si fCHu'pL`-4o77y'8m Dd2_2o.Ci/f j'8k'rcChDT:!ܕgz޵胂QnGߴ=Ӣa'{Ȫek|G҅J!/4)u璪Y*ݪi<YsY _~ 96 &}%#pr8+{u7mB&dSC"uQ.jngqV3"],f^{a( "OD7a皦4uB Vt6ڳ!@KIh[+z %i~sP g ]s*2f0瘎<`4ΘL_ylkN,Tb*Go%%/_`6X\Ov3z b<qb"kP?}I޹dhRjI,\ ۭeHp p#bU9IyL`뾢K'GTX=o 8𵭍o3}<-)`9$_PFqY}6Ɖ"2I'>i;jҵ Kd u M‰JeK 38!"0FDz hچs$r/z̗UAE$%[4]ۧvOmͱ R13HB[(N. 5B 7a6 o MeudM ciB"L"K# ʯUO! K&GıCuq;vލzGnco~.L{p ;#8yc Adobe Photoshop CC 2017 (Windows) 2018-06-22T10:02:14+08:00 2018-07-02T11:05:22+08:00 2018-07-02T11:05:22+08:00 image/png 3 xmp.iid:d25dd608-d1a1-4345-8aed-f31ffb97fc5f adobe:docid:photoshop:bf20e7c4-7da4-11e8-92f2-d9e6550a8a6d xmp.did:3a170e97-9755-d640-8f8f-3f9b31c0e3ae created xmp.iid:3a170e97-9755-d640-8f8f-3f9b31c0e3ae 2018-06-22T10:02:14+08:00 Adobe Photoshop CC 2017 (Windows) saved xmp.iid:d25dd608-d1a1-4345-8aed-f31ffb97fc5f 2018-07-02T11:05:22+08:00 Adobe Photoshop CC 2017 (Windows) / 1 3000000/10000 3000000/10000 2 65535 160 160 4F 5 cHRMz%u0`:o_F_IDATxMv6dnm@ :i 4++(+(= T:hgVPh|^V4HJust; .7}Cހ坾wl叙uM1,uz뒱Wd f1,bY,X d:;NDH,FSwS8W"OTd/w/=*2)Wps C( ƴ! [݀0+@  9]n5r8L %v,vK XXcu_@ƛG1h[߁۱.b&k{q)/b^Em Ja^Xhe+q(,]WQ :. +K,lCyU[XRBTWJ<x<GJJC+W"u&/~%źebY,巸>A]˸VcZ\6ȧgƟ,Xe氟՚LH/y3C* !8׵;x&rdBJ+~'wț2nN=K8JE2r޷\YD:x&R=!jCy^ЍibDȗKW!.^5!sкTYV' ҥ>w, O@%̋ņ[e|'_ dk YIx&"۞!_ry`r@Jv4;x&3Q-R?`v9; o0з%))K] o3d_[8P2"rƼPӠqDww?n(DXHyLӆٯD1`=GqޯDLk# !uyqAք\.jaw<|+~|#8k3ynrNn*jJC @n3yq9hZ MWa2BS@TAwdܹG a]bJd}!U~* ԩ3`p:Ж,GP/g^L3#sL<ԭǧi݃㼙^HV Q>#vf%kS2 ]Yӵ}F0*" Z(b\Ur7 /Y%UAe06wW7WL׿୑o&|j͡6$$w h$5 0ԴYbLlt47)ļύ }wlvW~SQ3م I#zϖ1YLg0S佰P~Wp-bݚڡ~0N3Ɔq)4pu޹H+62#7dba|{v'=^Z*t-vDa Ҟ&[mɺ?,S,6`pU'f=`1zWN*SoILs6 k[݂uVpja-k)RX? Zq`]_ &YL@|9 i -* V5.xk0ސhpKNY ba M8n',ePasK;?`٥j9Fs0txNjnNB ִ !h 45κ-`C+@w!}o?W,Kk+,*[Z?%Kpe+:if@,fb3>4̺ksvU-mlb`ɖ2'gmTω}fOyaX5"\doDW8eu1$~e=.k,q hdh6iua,!?0wKZ-]W#~@#?ԍg4;S]:?HwhIG}4$K7i3&!E}6l^#rԏgbysv(C^jI8Fa YkCd9ޞ~ R?ҏsP.v9Ѐc7"we<i[~N)IN|:Upk67EWVzQVGХp@{!Tpmj)Χ>ul pׇb΋jeۀ->p|.;AWKXz"meրW2w<5]@=?MLV`n9tWfbG+I`c9k,aY^0l}K*,]3 >w*$1 mدD<2azm)s- NH6|SVib>˚"y`ZY| ;:s)Fp6n/@p~#u\|>xxI 53|ܑb7]QuDTd3L(^%o"9,Gfݍ֢,mVa0#M+켫>ƤyU|H Ͽ1B\$,InaMVFaہ/@T؎JvUZ|KWXVo:h\VٝhfR 3b6-sx/$hz0.x/ 4l{0 _O/})}@y}nKcA]HBKz0-|D^ao°o2Aȅh'!bY @d1,Vɕ6ij+~ X -F p IENDB`ukui-biometric-auth/images/FingerPrint.gif0000644000175000017500000006105314064326115017557 0ustar fengfengGIF89a0rݑv\Qkf }ʻ)`viաP֩6vC\PTc&䠾/Me뀩7#Ѱ8GȄ7t٩!jFp:~@}n,ltc^~ǀ pU߿ɺζ gR! NETSCAPE2.0! XMP DataXMP ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!  ! ,}J~}J;.ȎpJѠ˂̓~Ԫւtp ϒ>K0gV9$nj;sI UcaeS@ (AiGprܹV|v$(0 ereh4cDT VlZ* g@ )+,4R y*h\B fZmT gѝV GC䐊رf؂~Բհ=MڸEͻ] z7$\:Oym8S:>9ٵcRݻڡ$ rL)lkC2[J SU}E Ȁ@^PP݂!sQѩ3peHz04B'`;Z!"a;?i }H2 sH[Lb!E)X;#T?Qkظ %'RL)ȜH*%( X| Br}A]r<@KRWс(%1Fg2>B$!Pz'ǨuK :HY$`1a$"$s2 LXۈPet3H"2B!$D&c`H.H@5a30B@W=qL\I36\ :)+q' OrҾ)KW j6&+ /qt9qh"!%広Iuq)&UR!<>Le"L0-&ʡt& %v۰27up*mߌhf32Gg}0qkonе+0.D -_|#E^h4)G(.y"MDK>T;D\IbQkV jd$y(ԯ-w߶3~YI| $P9gGt`2`%~&ݣG=_~' U6 WXG0ӯylEuQIը HG`dZne$aG>+D=6EщMG#ʱEFM `HТXC.l$$ӹմtcIFl/{)gO._!+YJF|J,񊬤(F2^eleE?SlDxuL?:F0J 42$AP*a-RSɌ@u0\D5I# i{}(?Lwn6·*Rb~&$(1Q$(HbՌf}J%y2D"XћdN2eRFlFTq*!s:Gq̡J#M؉ |bܒ@rS\Yb`~4rU#tO֘f ;qփ@DjuGewon@ `A<Unmh4B8Ae20GJ`M2Xoeۼ򔶂6'oOl'7)%ӰM'˳}=􋈄840)C-i!&BMz ]*Jk 'qhӘT0jd90q*Ȇuzl .Shnn .. CvV(D/m`bѪI+7=Mzu4+ qb:`gA;bz@*:]lhXFbkq;6نÁ૙G9[̏X ;[~7hJ=&F񡲺EQ czd$y:Jd9>hDzW:=sV %Yrcz!GfGӮ򭳝n !wwڲ.C4w}<-. ! ,, +$$<G8YDƒ:! #`JQp;re\s\r*2 DvXB e Aąd8&th F bKĉ@P,ŋ/: 3b@X<Ək!d=YbNC QƄ+`X:" R0HȜd* Z:%<&VZK.YƝFf觓Mn|)uRYeVfZLbօܥf馜vz p Qjꩥ 5xꫮ B a뭸Qp +,2~B&l  ,kqC ~D-0-Q覻ŸLp\ZZlHo.Lk0!! ,~,}J í}Ʋ 999ͺ,,MMθLx+^XB#6d0az-˛<xA W0Kv`ߐt dl9 e&RH%T0}`de矀{_yfYJ2"ors>`W&A{>N#ꨂ#Pal(@d&HdNI94ф*@CCa,N1 lKPŴVõVv:`kEnFଳ*;1D®`M@Q.Gmp$ oEKC hÒSH" ̆l»J*j3tl,[껯jp )'L D Q44Rg V/A ZS]qChgQl?04o= |p/}6vCTC .H ! ,"~~†Ɵû̒ɬҎϙӏ,׍Ֆ _%F7Q10%I m `ÇD(Ç1| ?o|$v 7· aʜI j4#} Y)(IRBX aMRJJ Y<|gGuB"E 6@̪Q`"ȏxBG Qgf}ÖҔ@ 5ٓ ƒ0>T,%F!B@ӤC?Bg)by0ӯw*1*}ƃΞ 8=У/_NLkPedf@ v鑟 'D+Ԟ2}u!PzY#:;͹ " ӎ;´ªGΕ6븷֖빊 Q8ih ͎o $ܯ gpj cKJ8YM4a4PDL L0D T/NP\-d^ZS@,RKM+4DAtA`MUxⅅmodxσBB=DG#MtSW ma밿^ywNlMu4DWO} 7p@ wGoG {0~ox0aB#ytvϕ 0z ; LpaM(P>7XL4V,0(P70/}!ӨI 0ⱌI%SOYkg WFq<+_ԫW #S/ 6SLi1eAvXg:Qנ@CAD#@:$8KT4O'Wod}kt_D~kS~趗n:X%uLmU RaH@P`/ fف+kjw4vXA,P@?()GC@#HA\"i!O[:4DQ <0,j"0avDgl? P 7؀хUtl12"Qe-80@! ,"~~xqq5ƛʧͶѵήגԤݫޜ7LQ)775,,QZ|0޼C0)lHŋ0ϔkh@I  ɂ˖W8|1IҀe tx2F 5RQ1b0ӦF뺑kgF{y/*Ȁ l {kj *.خӰr)!'̲p 7w5<3PԪ~kB5CM 41# -x^ 4!9TPdw޹X FD8k ;&0>ev4iBM7I'9|ox A@|PCw .z-` /7C#xߎP8lw< 1Q36؀"@ ""ap D! `>؀~4 A @?EA Kq Qh?pylC 7(`1,D~xeG*"@ ȁ7qk Q! ,~7Q |QL050)xxL6|x"0Q0070՟0ӂ| qqx~ ~70Ъ6QnClPԍ|8a(jTd#@%7VƓDL0 ȜI&LFRJ1e8)TYSѣH*]ZSAqNҧ'1"3邯_s@ٳh5iZF-W;l ?\1+^ 371Q,A' |ޒ"^1ȞMvPeV^ dt$,8,hL2T ⣶@֪-9,O{bnT7=OAmhOuY<N%'"}F ]vC!,IC[D5 ^~ l@8Aƥ2馜j駗1APfDfwKfFIVB@jdFz0ѩ&r Y䃭hYJ!J+,>&(`` L˶`o (²0*AP{jvfp$6.YlA pD{B'ˠ,|r& "_Pde3%b irho( \w-3\OW" `foq;t],j"Ko)'#x(Č,|3  4BCS4M7 Ќ X/n/޵ʐl5 @ڧ& M7ѴW 41iSto& K,NPo?^HQ|׽!D^;ء bQl]XgQ |SX-8`(XFDؽ)8 XcAe8HIbr-= &5j t"b9‘4 jF 3@ qdB)lMx̣/@  . e%+Ip cI! ,&~" |)5q7|)qq)|xqx5L 0667LQL7"۲ )"0Lq0x"֓60AB T1~AbGS%CW!bɓ'q/IqX:Ǝ0чɁulY.|AI"*bbUjU4"i³0QLzK4 ݻxz( -v Gm Yz@˖ǏXr3ks((>6XEGlEKgqV%LoQcB ?Nq7lıi[W#ύػ60mnh#jTL/_!ٯG8/>tOu7>a VZf!1^| I'd馜nyBI$j⡈ 蕍n{zсxi)v@A$GVz:heOt EG -+!AJKc*(& -:A f.d,8t| 9j{ Ú.% a)jgB ($*Pˠ #< ,j-Kzb;Uᜰ;Sך 4}B(0 5| #h /lh*G!l{vMj8.<]2{B2=騧} -m8"8!e@im0 DKptǾ/To֫2/${(>'bW_ք: !?002-^p@K H z|@*8@8#@p^CB@MȁJԟMɇ\0?Ѐ3!" p^ЀL`΀$\0z "@&0p5a E{@G:b:X`)щK! xC3sRƇ@VJJjxhcRm!(GBސ>F ;~ɂPOTHI.\ QR@" IlLOn`/h+Y4/AH8҅JtbKT[CM%AGQw؂x՛# nZVW]Mís(Mzlqh_!(ӨQ#Q- ػSx\)+U܄t 5jJX~ KyP\Wx3zr#}CU-g pz5R <(_tAAs˙6w)dY ?ݥ%TU9]1!,-"O ]`h=CUWHTZH=J1sGB>(.\v0~0#I !U&$dErCs#H^ E% K1`:Fn 4唒y<+k '8ѷ {>:NȰ KP#jSXG4(g8;3% Mh@2  D$x& gF` @ *P8ԁv}>`"q H,B؃&P!r)LA a}*5o|Lcd Y0B: xr>GТ AHH@"iC2B$C..&L/mE" 0!EDVHd`0]PD~KR9EL2@! ,9~5 || 0x056 6q)77)0ĈLţ50)ɉxq؜~7Qqx57퓼";)`t0R0EM$"*Uk&b#<CF2 ]$oKAJpBDyX/!eYB,*5)=M*UjCDqu 1&PjUٳg m[-Eis4' aHYuE11V er&Cȑn@Mj&|)Znc8nB7Tͻw,%ضDswr0tMGkTލw+W!p!|k#gLLR-F\l챗^y>Ä<AzA@$ V%f[՟2%AA@߭yzd! q^@id?@d“RwaX(1V?O>i$Kv0Aiu 0ApmFi^ _qeT_&Y g^‘x*ꨤ APp! ~%my٨ A!:d?I*8@Ƴd0 l0A**ZQad}6+b}<?, B,'` c0d:@h{’8ԙ4PeWRPgɍYBRxryRbیh}3l o>0.wy>`4"4y?- b tá4:1uޓ>4]+TR vðh@2 aD '0& #/8 KX'PAtP CmxDTkX%D2! 5 h` PMh}@lpo 40<$,H4 h u 3b@D/abPC X̤"N|EP !+aFq*.ߑ.쒗.3C"8ˇL"K$! ,B~Q|q |)67|5 qq"| 5Q0ħ)0LxLޠ"x؎q)"ˋ52+V%t|["%3,~@뤰RAO cH>>!Hb'<"Mq$PIfɟ-%st@DD#ЫF 颮6мSBbC^,NB1eG T 6CD GQ4rW؋MB2UF"@|jI͛Dq%t`  ҡW6L**9Q>o<tU뷶jEǢn]xnĘ] o,[{m/^_HL9-F(k.qFߺ~5|-iASEr9 Ȟ=MhJdQxQw_޲gزTسc1٭SvF.sLiI&_-M?R( 'dy hg yM\vgDv+pB1 ,Ë/(/آ1XtlM^fa1%5B9 8`2•W~te\n8Qlqґ$I4qYt'Od"!Q?l92eFA_5a&A}$]C2J _B+_b%f+`g>\Đ*!.*֕Y*Jƣ Jƻ*``ﻸzہ Ԙ mۄ~m˭ 8'[*O(^J o H 8؋#,&cpl<`jVy m;ثA) u (T8T-`˫bP3 =kA_Wqz 4W|Rk C'.O{B}vj yf^Ǡjv xmT2 n{2nrR3_pZ]VçSJkI z-cp*~&7-loʨda_8/ TOjEppVA>I (˷[sXo-Zgm#nױ h9b9 -a#S 9<ߑ,\p2, -B(3W(a3Y'37M2l-9нh FWQ| _A}(gr5+47mg|m:|t]<}ŗg5!\q)'G‡P'"ÇUa"%h%Cb^ |&B& )ओDTRf9eu vXc<0h*P̏-_>@@(Y> f}pfRkbn VGΗAl$%Q" VN@F p!`b M`MdE-]uIEzg$<R,hdn b`n .dj Ɗr1kf k_= eRHg槇tI(-*.2p s<HĸPo|$8r[@f~dYlPb.zv L3=8taeQ 0=lp%Þ#Sn-pP`wK7Sau*-_TWK%6"vVBooO#`Ӎ2o.ڗ\h>[SkWokE{*Ƞ #D/;`z-nnޞu+\79Jb o FGhw9 }  7Ѐ#Ng{Ӏ5XOe,Ϥ5߭Se&A0!`3#@u@Dx^p&:-*EBz08 Cp+{T'M\W,`Tr*aLxBT! [42c iC@_\E.F_t f` & c_xk<F86k;eC ! ,^~~57|| 5 )"Q|čq6qxɠʍ"Q~ݣxթ70|йϳ dnmLP5O!Æm@I5pnb:|mÑG*(NQ%I G-4OkTc٨ !'Xtc{ H*5ɱ,~iׄ."jC1y5,*U[Fȕ+]Qjԥ~Nru̗Xj%Z}|.<9G015gF*5JJÂdF \{(܄o!1*ȃȑŷ&K/*`IƬ+F@w+KY/%Ɠ ^ +Hͧ5uٽ;hFAywAl|Æv!}R@ˆM8a~ Wgk ɥELƃH! E L6$>  )*> huBRS}QB AQ߈NBO0x'9KR UWZRaB m5YglxC ~ ꨤFYNJY__I'0JR+֥kRࣛpNd @Ʋ2 H`ؒt*klj tȊJ B+;Ӷ/ؒ t0! JB*ڙ_K ۣoz:'x,Ӣm- ,|֢>ˬ +̆Cow( ر h-`2d-O *ޜp 3''qi.n~t( 3(\'^ӎ`VMe/mHp}]N?-0'5ᅏc0/ 22d0 O ; ޷'-3d{#QBZ+L `| H0De 2`@ ` t@y|H!Rz/$a I p 8# @b4aC(Ch;ء Հ(7AP-L*D0"82Vp)[ pC q 6H-tNhX@HB#D0ƈ"Q \hy^EL)A+Le l`7򕰴*cZZAM`!\ hp&NHD6\ǖI`Q~X4L䡛D ! ,g~57 |7665|Q~66"Qx"0 qè57Qx760"||5ѹӇհqx"Ρ.%i*z[-_ T)r2M\(L`$vO&Oq*#0oa5#Qʘ@¬*MF*]*FM<ôj8Հׯ^%1k-{*Kn]$[n1b.د[ep``WK r@/jư\9v}"a҅&-^#r,>܄Y[ o|g "Â<1P0C f AB{@|9@#݇J~A6Q@QR@!]va` *UZ~vxCuk) ĉFwPPŘslFi~@dk,pb 4묱Вç8){Nj]D@V+YeHi!,Blh8HJ0/|mjE9pj( ] &˯ ܫ,(l-B*+ Xk'!L0Q&÷Z%?1`<,)<ʾ TOW2@ LOnpXU? }w㎙K4 *Ȁ/'nWu)8<A|m&l[Ͷncto|7KBW/0^T/4Ah|y7M!e!/Ѕ g0ȡs@D!z`Ѓ&!PٱC$SVf .3d@2Bo(6 /A .QS x:6т|xJb-*! ,q~qQ||57|7 6"~5|q q5 )ű6ɒ͘L֋L0Lˉ"Ë)Lq"x0|x܊QJHFVL:ٻEPm(O5 ŁAQ^#N yhj09h.8D܈֪N0SdjklHӧ %0@*էOmIc&УŒ ST]d[LKW-|˷HQJwa9r@H["K<9$>rU} V, ׯ@s 6ٚݣGV]{5+VTQAu)j\; _kQBڪǑ[VatGŠh $$wBzі|ЗEZ~w >u0 &]@amjYh@|n} Zn"nG" Rt`P1\ve0H#A`ݎ DdA7d-"xOFGhp`j衈 e2ǃEhYޅp"'u(b%@蟂2@ƫ2 묲J` ^(PD A`g*M ܅0⧋YDM`b~ȓ+OnZ )m-N" U _q|Y.6?ˏD >a`G ZSsiYpw  a Hсdv!Gʁ^gmRR#uA p !!ȡdhl L6?q H!z)؄]Gmv(? 顒 ``ix$svApyul`1*fޘfxk^ @!gl!*j*j|Ωh%ٖ( mDꝎvȩ8dF+ҚjsbZ+t&wT=/}м O<D_F4H10Lt!< xC7/z@o :X,B /\CfH!?"\HF%68iC! ,q~x607Q~|6q0)"ɰQ75LƔɐ"q ١ x)LrGА75 ^ &XD5 ~8"2lлՠ#J?"q$b;ӑ[Q|ePWX`PJmQ_ :*HkIlIEٳhӪM B5rEiTFĊbdA Lp 'EX[W89wNO*N8 A?MiӡC7 ćc2%YYI*tF~ +_~) qgeX{fMzo)Rg =oߞ?|CO7uA_FAy)|!DVhJ({)W\F@hagSzG]n $=Bq@)~!yxt#RW}w-X7"V$ɤq#j³- N m 6(DRh雙 ~[,>; +ý[/>۪Y&Y#؉'ĒޠX */ { ,*/ۖcfʰÕA,ŋj+C#mH2/,# /D 5t-m-aanp@ aǍ47iԍL! |0 K;1# /xxQ^dS9@a 3=w#sQ K! j;d" ai}%@ eM7ꨗ^z=,:{ι; so^XkF=X_:OCȎH0Fxm( /])F1 ӄzmysh<mn FDlH?,p;ukui-biometric-auth/images/FingerPrint/0000755000175000017500000000000014064326115017063 5ustar fengfengukui-biometric-auth/images/FingerPrint/08.png0000644000175000017500000000715414064326115020027 0ustar fengfengPNG  IHDRbb3IDATx[lWm;vM۔ҖH$R@ȥ\@\. B *oHx@B"6%MFvŭ]'v,Z}3sxfNh3g{9Dd< "l)Sr}@Dpo'Ll3]modн]]&?:4u#ı+qV7yhY醭7&AD nz醔%!Xe{=G}'I[:=Ap8B8&nn.s^UCޡ7!"1[8AғLtTFUڝ?@GK#ly9"DS(DlFO= WHz({$?%_bYua8Y~#jBT>ǫMvE^fXDQQ;v41@Tm>:]t tC^s nz `QGImga$8Bx]0ofep\=塧FB8biDKV_ lI_~Bh4FDH:*ۀY9Ym $F p.o~\.Zy)p{Z j%BDЏ sxUmQ;)>k7&$P2r8>swX%߮cTNe/_xxDоĽYraࣶ\cu |x%JFL%D z\ 9V0#_${n \|00 |39$D֘5%BD ο S/*˒""b|jӨ8ګd߶BbJcM2Mt"q1k1uqp^B{jLBI# KrVˆ8^{wO*eyIM 뜏kK]'m\Nzd :* !,9f !i"r 0>_ }ZDHcNf`TDBgmG5F+gB*XGb,P[DvX”kَ"TNh2=Yv4Hؒ'<۳~; Y+G{թ< "#`T=vl ſ/BB8$"[ GJQ)&!TIu繞ED >/taΈMURpS7˷抩f;mu}v T"T$EErNQH%F#^'Kl±™\\?p1p,a7SmHS(ef]5*#P3Il^¡¡kH뾈N 6k8G*Ppg \R0v;286kfa>u*(+`T`+O :\ڊ]#{i1sQ{B=rsFĂCuFӞDE5&%4([9Uߡs!gtHYwu[4MҬ8S#E6u{ kxEY~ SK.ș܈卼GVaB#bv\7ZE#D Og%j-KG4A25vjlZX/S !5>Y=7t_#%N/碌Dv)|=/wD? ӈrȯ'AIENDB`ukui-biometric-auth/images/FingerPrint/10.png0000644000175000017500000000710214064326115020011 0ustar fengfengPNG  IHDRbb IDATx]lWvčۤ)R(U@DRBB *T"'PT@<ʗ@4IrڄDmƩLJs쬽FwvΝ;=wv"ȘU8"2ނ\GEdc-4Tg "۱lcǣ'E䈈nZAH㓎#5uqmܺuADN,>qz7OBc.;R !=Gh|}8d.Zm`8&BgNv}8h!Nb\z(:N#Dd :?g[IF۟2AjTDSq'EgHF(G8%1.EibY"1= 3!jOddBI?N{IѤזN߳ _GAU:vuͮk ]pݑwBÚq^3Ȣ$ SUi:M)iɜ bWC''C*_D ) p-hBǗ5m䜕~]о=_h2pɎ"$,=/$dQRR.t?@"YHkHϮgPL[ǁ;/CBT^ͤ6r F//PFFW>vc5܈F5; |oC7V&m!"",^>:+$>#KF'ddCБ}/QHEvVQU򅿈%dE5ШYAf@:L]f$,f#h0k;J붿Hl\E:JHhe"2ZD F]W( Y8꼿ByDġHH2 G ~t/#oi֗YtBvҾ# h< w w?V/Dm>[ ̋A,IesV7knt, ."{QaB-@TQkw6Rr&|+lF3!s*:+Vr< "{EdyF#nhmX;>FJ+V oT56V:Lι mh\D;U'uʼ2$ǰEk;jVځ:M3kf9snڹVҌ蕚'쮠Ne?RU@nk7-E-DX9U6[ٌ*Z&β|+8{ƝwWW.GIGIțm~-(/f>c`% |GK7; cYxSiC;]8b&ii>A1-z?1,\݃ n&_D1׆UQ'jKَ#_)1vZ9G")7q%uZ0AmECvx%45\ N^h {BojC&_$^>j_/C"mp"A3.8BhF^f=n0URa!JO@E7B=+KnI,Z">ѫ0vjP--H;RԽ&iK%GV!x5+FOaIުdyَWp+Vׂ!ё;fQŢE4jd;P6z'i cއZ!7J2vtt Y[Rniۜ;?ȹh,T Sk[߶Yx[iֿthv=jPt|/\a]"RU X?; 7ͬ>WN29\Eg痪׮XD_AmoKft3˭"]^Cs\Bjw`#r'I=یfg۱U;T ",ӰH2nϲ{MQ`M䫸_)9^nMce"CMH[Iÿx/=CBEd х4wSN{YaS_!_qҺ!+'H\z2?9utǢң}3x$c [񚞫vH洂EUTg իߢ^<IENDB`ukui-biometric-auth/images/FingerPrint/07.png0000644000175000017500000000711514064326115020023 0ustar fengfengPNG  IHDRbbIDATx]heW{rD3M:)mV[[nj(/UAAQ>2EPZR&2d&5;M&^+wߝ}>9v>swks.Ei9[Y,r@!"=ܟU*q?2v*tp򬈜 ["r\e{6dm=0PB Cw`|S3{lM7ADP/9ka&V ) ؙwνZe{#B||$pBz 92FVs Ḇ毪ĢPthjG4Atzy(ӣk I{2q9xmiĔ)A!>rZD&zYJ#XCؓ]D ~U߈oDbӎډ$>5]=@u2$jEDM?لxYvGv@'"8`efAmιF#Eɿq 0Sd@9"v} >r9ra@^nn g݄dkE`W v|ڳ TnDm[|2:$#KZ#6 ?uL6|IIDc*!BMгʐ +)s"nMSI*"n $ x<TnKxuN}NwÏK7eH|ι`eLF(p//ׁrfН8\~'&|e Gń . DDx?Ԍ~k+N;(0>`R%{:҄4c !}qI |LPv<3BƂǿ+LoqCty)ŚeߵmLDF8a)Rom8?gTadUDFMkz%#DB?p8~e /*ִBgi>J3G3x3_em$iX:dd%P32Dd9Ԝo!dk=x9ƏWŢ0-a4|Zİz>Xr*8x'uhv|x0e 'io #qН?2pψpfw+/j7͎(_j'8׆*~{yc?菏 z^ [<iѓmcT WU@X|ȣ*?)!&mma@~;ؿF7qd)J#ܜ^m *A tw; z;Ӻ%:5h,[;vq|&sY1szm04B 2Nmιk=mKc$@SJ1ݿ0&LuxXwέU`h K/Ԫ x{<9o;)HksnGmsM1&!c(s[rR~|ah~hy:,DAR{U^kr_~/jmd{1W*Y3@{(ӏ*XYpܪS"2[c4>-7l9l ιP")Zg:*'BDf9.5Ra혈-KYVj&0u&UYA)`+ߘmT"sωQsj??Q)*%B<Au+9Kڦ "\¶$휻NtT&,s~HǛچ[n`ADv眻)"x<Ѿɜg+C>}`0Ԝtoιsιk^JvԆB|mpeD9i=̺9s=kY}_&S'V@OR#LE 8B;AXu*3I:H?koKJ" k:f&I3y᧙k,{jL0Z$EB=s4bKˉkFY0뭙P!e}աi}Ú& E,B GO Ԗ}̀ 9e!ea"gӴ1&ija<c=KD<@e#TB͒ r#qΜx^ztp SԈ-~7nZE#Du;}r(6cu=f$cmRݐPT4^F@D,UfOBϭk蘸"TFDƢ<$ wo"yH. 6=mr%'Ik_X"gN&)LjY1(F4sxsԢcRGLMig_kFPA'-Ɠ*q Yi9-3MapOϾւ1˒x^'45_tY`DAQSM0$Wiv-#Eio 6/J 979fv}M&{ h)gmS-hz>bRKdJ|V"̈Zk"B%29 W՚G'jGё9ݢQҥEyu]B| Ɲu5J.y{E[Gx!cԮ`;&t_/zQeyhiiNKdf42{"l:~pc;xbW̮f1"zE5ϰ0MJ@DD9ZGm_321D_ 7[łğ121D( ̬XgR]9#KDDBllu+BQ2MPI1O++Ose40 KIW܊l#Ԑ.(mD U^HAszDsM:8CJ3m90G8fn .ʈOjP{Jș>*ZR:#"z醲IENDB`ukui-biometric-auth/images/FingerPrint/15.png0000644000175000017500000000670214064326115020023 0ustar fengfengPNG  IHDRbb IDATx]]W{f26CFՌ( 8WAQ! Qao *LO,*ڀ"3ik M43|k嬳{ϝq}s{ 8Q9+"Kb"؅LgEhY ]bmJr[H ;N.im"2]r>ON\Ja۸9KbD~%Ba򟪻"U;[Y~c䈐_i& ,‹} `n:kmjXR9Dg4X%z^G!jUhN\"jK- S#$N$qt?崔OI,JٴqK"B¯LH4N2ЦC'6zEסA? ^]'V }:Կ $͡k΀f'DLa 9hhdc+é.F3l[4 QOJV9BxQ#gɏT9M6WN>ME?ӷJ&8~z_s;Z+l3ąM!qt餞;Os"+wFe=g!!diZ7PA,%BBLw=dB^-=<1%+f14(_[hJͪc 9K\@=1n˭NL*=N^"IwƮU_F$Ni'Sɩ&vhP< oOk|?JsGL*\{Hd/6[_LB.bMy6B!=ud+tZᴡgPCtR3 _JFhz(1Xqdumעk}5WEJԛxl.r\2ޑQpNxB |nL Hgsv~^T„Z!| 6Y>)# $5M#gH~ڻT *DQ*biбdoƴU{GVp?* ݵhV0pz|yϕAcɶvw'P>~gs"P(ن}CH銂lPЮN}5@p& eIc/VRE8e׉{ U*RHdzmɼs3T`P$"T{uq+vqֈdfm#0ͪiNQ6fh tRp7;\gʶQB h͔ R 4:Оn3BSF7$.˟#皮oC\wV :\k5pNe_pBi^L@o+9oOZDقsOjls92AڽU:Mׅ% $DY-Z蝚7ԩO[^G7;I#f(' .ihPT Y:8CΤڠdsEcWb(D)2V$?:CE" D 6毈_Dd&V֏%u"Ϲ&>Ef~ E&|O㚿]TfUBꪡ}°L2m瀫"2Ϟ&5U'DyM0mMb"."j1緔-`C^__Emdd~< LRz}+bȈk< mĠ4f D4&KW"ODJQZ8| ,y6zRD׈1-`{B|{~ Lk,y2|Yy|AFķ4w7yz#D2HD7, !lB#{O>|~5\' 58|3m iC [>n($k~2"ZqxҺBOD`ǝ6g`r"R,+;dL.O >-"{-"i> pH('Lϫz1 h# "q־o!-"!*]ha?~bd`/)#cM?5Wd L< [^I)ͭF7DBnVՎPɄmTD'~KMdrKD-&Fm|ZNi2 ^ExUv\)5`fңLjn/q֎uM|ei9%p$x$Ik4GCm{ecDx88&!7-b;| x5K0oe&R4θxF5DI~0px"1,z͸hn*U4͐A.9VAz8ޛ5ȫpo }w(!-#"uཚc {ɓabO6…hi"IG6 1)6\[[Du'\;_e;7m10ygU4&sp>gfSa)<sE^C;`̄wz ~z䃄Mw:N{O+r)-RS "1 !,ehA3 NUBx q?k]u~bdPh"KjGr xڏn0rDh=L\qDwapX !\D !|gX}D!$ƬnҷaUCfLKCznT:\r^jIOĊpMƆBoWܒq,R U@Gvl}cv j#[|huLkξ_ "A]$:s4cP'>G!K=5I##Mq)z3p-Uʜ&jĸ<,#KDBj?#0e"MH_IHq?6BLC}?"fi6Bo:1_G]aBD&(0!cDc .DCB}?^0`2_-HM)?(+#N {xbyd Ԯ]ի|+W}IENDB`ukui-biometric-auth/images/FingerPrint/17.png0000644000175000017500000000645214064326115020027 0ustar fengfengPNG  IHDRbb IDATxKl]GvIRB Q! $R 6 a i%$,."_J( qR(얒o|3{mь=9Ǽ@D)YTKRR 9y#y7\qkC~!f͏+"rBDZz YPٮy?zhJǂqηYޔqGۮnU$I+?vEB5֊K&3hc@GyMuVs@7Idn:,hUX}Z"2k'5X%m紼^E{ӪΤiK+lS PNZ7ґ!%vh*y5~+fB9\EPP1/753@u4jЉЇoC@vzuZDك\݌U`}l̑F3H{1=%Ipjь;!Q0R!"G$9#d{ü&?V3J$8~ͷ\-+t1وxS׻] t\;:Hs"=Bd몑%BgOY YW*@C_1!dk㎇l[,:t_<ks HV\ߩ:c&C.ԭڗS c6Z u$ۏzt4v5BhB%;cW^xx0I.# 5M#gېw@TTRcaXBҝ1jo#R_xYFra` g}3n5YBݓvV`ASec 309wj tl] R0\ ifHvwtЯH(+RXI)pʦTm%KR[_0`ϗy33(X0W(b~bG."նU qi#oHj _voV E%MF>CA&w4-B ݐ ]R tJYyNI" ؟Z\mpߵ#Sхqe;<";y1y 4sysMց~s~Qo*ZUA@f*>{Q?5y!w#}vh}ZDok-;FPeh(<,6ݢɡ _*9t8h:4w$.euZ _-d搓%QTTǮ i!:'_I#NS暼0NqJőC^e5)عcqD;O։ * "+R1J@H^ JĊ3-|Y7!bW JU{D *r.]MA/pNȔifM 9ϛk&E$1+;B_0 (nlkӇxb1u? Jnclh I/bDhK sJIMS>M%n>zɏ#Ք$'}x0pT AZ";R6H&.sOy7pg fTCGKk΀I("2 瞐8[ s8a]!|zK :&= ρ_!>dx&;Gp&y<"m^kCHMׁY}NF;b[D<ǀI5f"(xn{+mrɭc8YS36zB6}ɯGrO=vmhH_D0M>)>$FAm>oLw0d Rs'+h7yXΤ:Vm"-DL ۖcLc/dl8d1", aЛmڧqQ8 0߽F\3ǯUՎZD( ӤDG%nk5~ 8/BoC6xxgHOU|ǔ.NSE'$XH&+}&]w?8b/2ME$I_)ݎ&I+;ؔy,c6$XbǴ[yQ<g&6 \t.{ư[UmpQ䛝;'jKl͇uex g .B+~3澇pfe8Q8R,/iͧ4-2GsaFgH^'T#D$Ԁc&I3a;˸1)+l:D="'k~-{P+2&jSfRd6p g f4tPQ!c!Qr兽*ԛ2ϫcٷDH[-8Q2VwՈp|ǯD+l_}!O+C8s0ky"Oi<ߛϛ;HȚ !tTW5SlKF^s/q/@G\-y^? a9L,{ /=GV|yX%բaBD5$I.Ӹ0yVLG>bgJB;qEyC'r4E"ہ6[ף Kzr I mM`z2?Yv"I)%KKS< t Nl9uߩ$n@M*omT|-z HIENDB`ukui-biometric-auth/images/FingerPrint/03.png0000644000175000017500000000647014064326115020022 0ustar fengfengPNG  IHDRbb IDATx]Qn}ťIZL(Р!AH |˧  \ d>r l@` LBƔYeKU>SYEz{vg{uWWWW *#,ѓ{r5ϗI鉤oI5?1/=1}J5C0='+`OLϤ)dӄ> "A_F±9WOs%!ˍ|ND3|v/ wE+(m!Rz3g!T1Mjߏ%?6mwQhџH|(%/}UJeX|e|]2,RH81mo's"dye8v$XHr$_SBGSUE5 6,K c?f /Yu?*H $ΫzcHKQEBHTMYk{ˮRS"x `!%L+޹VTklO ~&=H!xY:[5Ɠ/C Vg=l 4 \Pf@\Iϲ^efJf^JŞP%ɟA ~%C=<4|!#ɟ F1:=&p͇"llSgxzqAq.J~Us{=~>rRz,ОzߚhBhG&?GC?2 ~h;0l*Te1,5~!)_+FagV&et gq G24!|P622yXN݃U 3-Py82.>h<+䟋585YvI}.CV< soz$[MNE#$ >bQHS SYE=-y7:(q*aa `[YC1y n4:): f6P9Xx:=pإV"kaz6|% an֮7}G][Dٸ7NW?s uqӤf CHD^Lb e+ CHgD0 ,{6PB~hD swL=,!8?ӫPd%"{ND{9CTpNn +2\CizQڂn:fބ#pcǓdd!#aGB!yD?vmFpxj,"b%aY(Tbb1(,|El0ȱtB= ?̈&a3_DA{jLFaݾo@@Dt$Į1ŶP*2u#\=gB?2Fp|'>fILx3{%Cl\#D-K["zFDD4F!f.qC.|.jhQ'-A#"z(7):f ,70jr(02TWBZf,A,hTtWªCaTŤ[#ZDXHj wcz*m rF33mN<5޷g1ojo c6%*D3~@{T!sB\F7tMyFbc2Afxf!BԒ 01親r ]mIHTwZfE'Dպ Ž>u9F`Y8ɷޡ߹J@BqTDZE6a \i'M& ynjKWt^&d_\tfZ6T\]Lho|n \k[Y:ח"~1Q < f& ft&Pٔ)YjB1j;w=Vz5}z:m5Y wՖ %aV/,r&:@w)ظ6ɗ/]MGu |P !r}Žs)B:{NHlStqhJazB!N`L76ɖ}I/Hٱ0Duno rkD3o5$3 :GbhB-C^dAgZgSu6XSmkpnj_1BS )IY3 6`+Q1.\a'+,GY?K=7$̬Gp3ɝ7Nzn+&r+ODE toV>2 Dv2Dukfz2Eu,,ƋWJWOXBpj񋺚b0Hxʳ"_3?"CB-xOJu|z&d*ɟ9?̺N-2|S]ԌXf\o8a^YVS Uץw Qj1C!⑀:!S?~^x+|@'rkeqķZ!V1S2g,43/!,BZ}@EN\bWyWOty CvwUzgq[҇Kg坆1QOw:;fc~U?g>|p{y/P~Mo1W nc_0 3߲kHT5IENDB`ukui-biometric-auth/images/FingerPrint/04.png0000644000175000017500000000701614064326115020020 0ustar fengfengPNG  IHDRbb IDATxn]Gc;vcb%6!T) @m 7\'(%#GN]2H0Tф "b,=euB OBr\ $D2$7!DDBLXkECyVpf<{<_LiMH 9y[N~l#$Xf,l#e"J=v x$uHȕ]GLz|GGD֎FD( ˌmDVD'.UYY3&p B-(4ŒIXb,t{dhB*6 ^9R*:]~ \! ~VWܵ_$/:5"Bl#!%;/5k_fT@ߒXk~^dۀdoEdԑPmrrz &m|iIcCElo9Bx "%b 0t`*񖒷 !ܝsAC? 6BZLQg$uؚ'B%BbYឈ >2e`HՔ!d0"D<6Q(X=!Wmjݬ;*Kk.p;p#W^Pusy;;P"~"!zXi]U$-2ixs%ݺND։@IF/D$$I(ȤVvonImTXED$$7HPa\x.v~Ek[ev iFFDP/$>EƥVjBDNI=.@VC1"NΈЏB,{!OJXP{Ynm+חH,D`3$j!A,D\]h7sE:VQ}&>@D=^]F][X|,0xI>K|!B@O )61}*OgDrKl;}#َ)ީqxOdj](':jK=Ϯ֪3fEn߫B8 !SO5UoUFۢ}T*Yg (9پ:)ҽmB p*"e2|2tNG] b ]S kx1hV;GJ՝"ՠ_ nFk !D"|Mt:%Bla2wJ]`A++"YCoMg:p_]]wv]#LEFKE^ tKL';tX0oCDFe!;DX~[ѵEFYv$%=8p3p70Gn-$dT vw r^_d (-L"ALi{CԼ_LI`6+`Xj 4B5\3! …K.gȸKT]k<#X߼]QW& J^u:,s?M-c[#FDjXN wP4`&C5 oYi- yDlJC1Ī&y,Bt}E_ `BΩpH]790CkgXhƘn/d/,Y:{Z2Ad~3#^7VTa5bC;RW@W-b"\o݈|Bu]AG`аYAʹ6P7qb(4p&SXWA/#4:b(I["\W5?A'k=Eם_o׏~xC u'7ޒ>w DMVQȻ--ty8IENDB`ukui-biometric-auth/images/FingerPrint/13.png0000644000175000017500000000704714064326115020024 0ustar fengfengPNG  IHDRbb IDATxoW?N 4 MIVB"UB,!X dv[CP ,T Z?H6]sXs6Ja7-{N5ݱ "rJeDDBݏ0HUR:3hOu+%`)@:Y,l7܇YM-^Չ:HCDm.Y\!KZEݵ!ZѥiHF\ٶ "$M]XRHJPJĂ ;ԈmIJ{~#nB;QC'>ACu߳ _g *NL_Эk&;hjp?g\Vi6s*Iq)pzٌͫ;`YSԳa,BDN^WK%'u OUǯE=w%Lc)#38$V!cN$x!9kdAPI=Bwjuc bFC1CȊY㮇tw?>%3a%fB\7fc݂PZZK9 +4( XE$]GeAk XJs-"c K ec̡%o0G~BxrGaf z_Ig +XN(VdØ_n!#\G‡ЇuHғ)Pd>jSF IJ#HY>î<%od_5O)|䶯// +zN(=};.Dvg%Kq ]jOsZ|}FG"&IW+䴟!aBE`祇cUDc I2YBzf륑{@q EQ?\C$=Ywwfus|dF?L DJ+rev}lBw#ɠ_P:j*R+T7N dI;Lmجo/y]-g:ۭc'BHETw#."IRC8a\ͪYirQV3/E 9-NK]D4JI+"t9 *"Dd[|AݣjHܳl2Mߨ\/"39Ni7^5DpG<$ɣ Y}N"lZV VaXQPam^s?M'c_w91C2 ڷIi- vG/Zu=AE|OgG5-L{C=wkq)`KtKtP O[?FsW_RNĤ3+^o$ mJ$ضal I(j{H 6$ohvFOm$1Et5Y"DA fz<63ϲil!O֎0"Ock#?Ȱ2ikDFoOĿu42ix(̲A"IG''EDn{qDH[ú!QȁN2fuDzZ-e$lqsMf~yo3n6~,dGDh h}s~ۻ,^nXr{ )B₼ϐ`gRO} O>,I!DB*Hg"2V`DL&/sbz^Ml6ed|\u(S*֦F):5?/KQGw1Y\jH?{I[$KM"|xL[!Ɋ|Dɺ<"N ""en+.007B<~G$`S(k55ukztj!Za"$܎`n\̈́n{Of;ĕY,&I-Xhg 1~t0,o#]O$._+#ڿl,}҅vۤý(8/h/poaQJZC2>k%9b\"!#/ 6 aݵ1% {lk{3m}r63 *lit{u9@н9)ݞdjѽLi?{,Fi=yn´ӴHlc 펮o۷-Ͷo}"#& q1uFAr=I|24M!,M\#q!nv%賔Js]%ƫ ؕdlmm 7#pks۝o "viFLcW˲ B&BӶWz.D5 ;}\QgYLsXM" U_ F OOV%C݋ wp>o#C%f0cYRx(p>6Α"ƃGH\uP槉ĽB͒TO͂6ΞS|`S%͹Aι-℀ib PZꀒ яŜ&H>fr_d~Jd|Hp 7D죓8֯T zxH.:+Ԯ]ի ,_5 IENDB`ukui-biometric-auth/images/FingerPrint/11.png0000644000175000017500000000717214064326115020021 0ustar fengfengPNG  IHDRbbAIDATx[]e;thZRjHX$񖎈KbQDc,&|DTbDLfDi Na)3sˇ}fL/g9"v9("c(k"2ڄ\Ed{Gh0c "+HCчc"r@Dto-Ddv,CǁǺf`86n "eٸelADv'@!=O ؍9O?Bxi5:z0l480 CZ2vvcg!vbT:(:A#Dd:ۿjK$3m3Aj5i{2NDSEjh 合Le1-hr@j$FV١XQD &2b&DԤhD3‰`7=!Z>u $jEDXP<5kd[PtaaX˘έsdl; Hr!e fmVޑ(:J#DdwEV:>ZU?GZ6 Q?3׶gzV"G24cMC4K i}D+o"K=Q3"dlZjaK 7F2rm!K #jK_lgHh#}b&3aj?[1&Jys 9>ݳ69e7G8#V Q'4v*5B5" fSSĮǁC?a܎0ׄƳJ4ڿm׏H.ŔOf\͏48o4%"Dpb%TDP&fG7{qmꗮ'jiG4 -Ql2&K{, Ǘ4K"5Gۓ$MeeuGF"r f9&~;/V :kD_l>u ]'"5HyHDnE$Dck{АFI4&JD }vtG]6>_hد|xt%_l}ɶ/ۀ=E>j-4fN"|' yՄ%:3VdׁOw !UD.3T=Tq?-9Tfd-'RulR v237=t}_[ ,5SxJ$x 1JzLB =۱h=OIiUDE/$Xod|s@mZd\οL!^9IX%˨̓Q*"RC "ZBDDc2c= I{W YۀM@kOP\> | _FQ"[mRYWHD cC$oA;Y='GH#wB<xl|J8e}3YGǺW!""}&]zs|>b=K N&4\8)40kwN+П%7C7iR>%݁FymBl8!(!Hi 0]$ 9f~1ojG+J=PsxR֧Q-ۃ _@.y;<[DjGSD }$r"|I&c2o'I,'GD\4ӨMa) n5@MQ\qnG㋵Mu#7)bg҇:TP0@mSvwuixwٵ@@MIT[3TkUm$35g(/t7 Xi_Bgn/O:&*TCz]hItո\`W[߱~N9;I40o}3S  #vYNzk@9"=MF7:OyUhhDlCgu[kQMMmalk%a I`mvO~-v5џj㋨I7I&?J7E5r654Xб}|Oky"L0k;:*p?/yބ,PMx#:}]6j+Lp!g <.Uam,b>Teuv?3$=e~uqZքG*Ns1( 'Z:ly5s$Ahf.Z.zxmMێ7 "2g8} LvuGڟǩ'e-,P=_wQmh?6)q5֯ *ѵI4Q>h;Dqc}\JgBsY.4rz>p>h6B84j;B8UƲR>`t6k_'43_[}kit bLMda7vw,4MӨ).Rau'//@VЇF>/Ջ絭ƴG;h,F'zyyE)r umN6b$"ݭxurW/4NZq#׌0S%.`W^2̼lF ZcF4:JXP8J:Q+}NADpliV#[ҝ9HLTyM(q2$M9;Πu!uҜ6Qm3k@89ꅪHL1ҏg6MWˆ덶/fPnQM!`4Ȭgl.es0%ۯ]w9QAFmoS7ft "}O Z*Rn[I}u_}z46*KDTE݌=C%2 F5!3+EgGDF`$ +/^nh -G Ϡ=J9Engq4y~U"JS27%̌EfCyV`Q@?&gY4B%TZ(fEM3< ooVP GGsO9>BXNŸ1D ^ޮYYmKl'rбDHUm!gԝL- i) >B댥cKmAᔈCMPn1:a/+k|fWK#?*"q;>\ސ,m=Ez35 QtO!G~p$:8*ߗlFIE-J,ۜfpV?b*5_8,-?{({IENDB`ukui-biometric-auth/images/FingerPrint/06.png0000644000175000017500000000700014064326115020013 0ustar fengfengPNG  IHDRbb IDATxMG$O`3D Y fpذ oy0+$DH$$2,ؚI1䚱s驮q^Uu>o "gDyMC !S oH>m;;L#")r|#ۉ"*"H[w"!;Cn􀮄Xʓ2U%"rPF/~ߴ =BfO݈5]RND?*XYȀ(KM+JGG{kM$ XF1)RI*2> >EEA4U$zqqﷴo$a[!DX}x}XUmAveڊDc;jQ >EWYeH9ǁo 0%FwHu{8rf q~^&\JԷ]ݓq*2jH(IH}5H1C oQn34:&& t;DL~_1Y5UIfo f eA( IuO\&!b#8Br*'%r+ُdX2>TToGt&G))2(#o<}BVU.*+SQY"jԾ9<|Mbʌ~ 8'xwA!gsPx6)qk Z}<圖saG\ b5ʽ(-0`nmŨzWBspl&} ~_~O̯y l[d#[NS8EO鱧ޏm[?PLSiqOBYHD1~ 3E4żo딫=wwL"1ժ@GGqb07^½k># joƅ6&< =ZN$# 7bz1P9-,Ym<-(*Գ( !Ǟw=y;lYe' `L:Ѷ;a_7s#7BW2ǝ/ VvYl^zY2P&ѰKM.{&Q(jIDzk:4 6TsDib'#82K5mZB'D+|y䫞[İKgx NCv̅Ц(x"#/րVin446gd%A&!(U[j+UčU9I&E=ݦSW!B@[Xa8jUU08쓽R:F GL"rXCD "XqZ2ݫjaU[xa TD^1%q#Ɖ̡KzsvZDV&2,I#iGzխ2ՠSj76Kp "r x*~VKSD- s׭f4ss"\CMI:pWM?0y]O|o3"׭n-$Dd''®Fy}Ѵ0?,([O Cٌ!\ !!P&/ݵTnlPPZ< #B M!7ט.zeo 05R;0330& a#{T.]r6AmZ]3I:(h6A N#UÜiF<vDX/-U9 .yb)A'TߝPa.shC5 8soBC ʆ:T|O!FXBtc Z˾R_tH]74m]a4gXj$gcL gh,NL̈F֣U-1L[rD,i#ud:s2*:!NYʡ qU8N?ɷ\ . G mM&QVZʭ 7׹{Zƈ(YC$ TO$U\ }.`̹TQT7Xn~V3"PWGBwMg_[A[^41$q'w9f#ǻe3&Qg{m~4ܬ }bѦjB{Bru`%lnFs%٤ ǰ:KyD ~^o\9t5AMA2kZAZ"S7|van|RE&Kd2ȇyjMS 11Dh|,;2[%,rΝ& xVDN(X'޽Fͥte{J+ kD׺i)Ԍzf mq`_@{e"M ;DbW̮3"fA~%djDžBhPὣV9(&5KFxK32&9,.bٖAab(P+;+B:'/UXI(\$yA iL[&`?%B"NtOBB+4VGKGj 9jŸ"%-_"?d&"rƩ 6!\pr?c;/cvN\qKe'=/"q;-@D!WE+%gd%IENDB`ukui-biometric-auth/images/FingerPrint/01.png0000644000175000017500000000537214064326115020020 0ustar fengfengPNG  IHDRbb IDATx]j&666688DpHi}M 7#y!:(V罽n\![:ͷ;;;38` 3W,`r2O |U"I|3Cnv|/(ӽkG*۷__^fn@ 1:ni|.0c-G'bf" [FWs7$̼`%Dtf{k6lXޠ `@D_Ţ諶k ]\O&A3@z.ǞKFn !y.G;e2z|3,, v ^DtB2'9.v%B S3jB7bSHn5BTl FU}H'I:"&5vU=u̼̻efNXM GN\gn2QGjlBe;cqsxD5 h635.:E3oWav5<:7e "yroj6CѝGn!kaY.#*3d%B/"+EJgq݇`HѹgO_F9ɉPA+bdmnTn.cHi՘h9$0ŢmLG^ma%77ۇD(mɩs&7:δUT Մ 0 dԹ=>&rxFS*d!BX3O%_ -V:N_)$f\OTIL1c>ѦFHp-mt4a}ED9uڄ8[5HM!y+:Yɶl>wQX< }Pk,u{[oz3}Ŧπ苪? k"ToRS$# +pn+Wz1=.y@wSRj^^'6P i"u?1YL"BDh<慿!#Y[*jz=XOB5Y(S jBI4[]ႈ1o s(m]=J !sz7ZWd:$BCMnMfn;0_yV106i38$LRhȾu7OԽkY:?wɕQcUF9TD"q{z5xa: {^uFL<" RYM޸Z5qM߲`Dd:\&ڒRYNn{gR5ٮjDDIL}Yn 4M:M}P Rg^ߺCn5 R>Yg/Z 6%Ax=Rd"~cYkuY ܥ:E:)2߸YM\])9:CcʀJ: $9:&xM7̃쓵KD;{>k G>.!u?UZr}n1Yܮp(н{ZcռZσdD8k;Gz>є}o= IO۹`OXY +]auV &zk&"yucK<LCi*;R"d]\C1TNZGgpvRoCO !j+3:G鱃Pk)?XQJDKU }Y)4N=َb3}ʼqBiaNsR3jR80pO,=)}hByNjQdsC3mAf (j/ :J~q:ON}H9NsFFgFFك{K=5,&C,5.fd_Qw!*d$(>Du7w-}:0qI":gk9 ܕ`EFd&+z@E"b;Wc,efG~פ#?iRd;^fm_:rjr><|ǎ_/xq龲 Ժx]V3iP?3`O r)ƆIENDB`ukui-biometric-auth/images/FingerPrint/12.png0000644000175000017500000000717714064326115020027 0ustar fengfengPNG  IHDRbbFIDATx]lWII]&$UiA _j6TWR7x@2Rȭx ^PB$-EU nRM'9;3_Ν;=_B9("'DdʶdBD&[,p r{"2Md+;"2VQ6-Ddd;d|qn!mY;_DԪ#wm5L!ﯺ!ea;RN9"Dj=,p!ܖFv+nØ:IUhʶ,fIF;RfDGuj8jҎAS)"23RD$q)ibU"1u|΄_52bSA;NnN߳ ]ǣAU:vcUͮkbnPaaʘlsdQl;WHr3!ӺM f|6/( QJV9Bx"_Άd<窲ϢYsmkfBȵvnMk%< q:GSzfrfS!sGiN$z}BIB'{&2LU6,LS!tB\7=~oUoAIŎaus b Fx슙$k -ĘF鲹@&kn֦0&t'&#9zuCޅ1%2NH N4I@7$$eLC*LxҚp\FQ a,t4_d%L'UHɆvw-m}N7ٞFd F5Di,GDdXD۶ͮjVOs :jS[d%oDY+]6GD#"|HӶ"ﱲ/Q"җiیjC !\G=my`}gm95y;kw_~~ge{Vl'1tᖈXeOѵ5vDίEd;JB?i2>ge~kЩ'v7H1 C$$>imsVx?DJ:Qa*Y$$dM[ IX.uH[eU0(p4f6V"D@#%Ia+i%4 ;ٵF rߤIpRY1 V>Ӿ_EdX !Qdh @;P:I1Zyb2,QfxP<9Ip;s-$b&!b!-n"?݊v?bRvZk$Q+ QAFBCp|޳Y;VH4QlV[ D')9p6욡hU:e6~']˨d֞ !K(!2-p" Fd wE圈ZtLZ3|+"Gۨ;jHYѾDmt":,-a$ ۉ-&ı4qQG̿PN>nTLƠ] Q#v+hs}/̶)`#(MDXy Ffק뤉|=)L2.w"k]DjihFF)""b!fI~~ŽךQɂF&qdu;J a+HGEɚ<"<g}42SM)}nFTۢsAb"|MS6v<:͎fMM|WfsOBFnXF#bڟ9KH^%qT7PGה9}L 4> vYS/t,po_F.V>I!tl3bHvv>kG4q4 OG,-hv-Fyu99h(}CDn #";NN̶QO(?@2[y.;OcGo!^ ^Cqں`Mג w C$~'\x!:F%y@w;BکYkX^;g;[І(oVu];mar5ZZ;X+z劢DNZb6 " e"u%(\m٦vJ3DX~ mvM%+ "gsh<("ZvrgmnpjJ܅BndB}>fV>E4j*s6mr4GPէA`!"[Zx[*_FD]6. 4 +,= "Q K6HFCp'I"Y_*e&}g׮LD,8mc6JZ<j/"I?v|*rg 6"L5\)QN46:8zhuՂET ",Ӱ Y@ֵng=G=`iew]-BeD(jra A9vaCj9:hx40'~WBk|i".YmClgȐPj6OTQ2QV2g^n|x`V;;"r ҅iC%;v$ؘ/!}oOꚴe1n>?F5mpK:6Nj7$y餈tR/ǝ H[ɊU9osZɢJǤe0 $zeqJ2?[mlIENDB`ukui-biometric-auth/images/FingerPrint/14.png0000644000175000017500000000673014064326115020023 0ustar fengfengPNG  IHDRbb IDATxoW?׻qi"ƢRi"Z $Px'?H?`xA)RēRIjKڤ v4='sfvfwƻ+fsν{~{g "'D䬈,VKܥ r2E.V0l "+m1[9wrYDΈ|C}۳y9p5PB ݵ~);w>d "'U+AD n醔Zђ/ޫ=!1>,~NtU" !2F a^ShWubI(;F5#DQ۟-UMe4 Ѫ.TNZqew`!q 圈h}-I)XiqG"B:oMHt3JR"hȉ8^8u{SZȉЛn@u C6܎ĸ#fNN2BhZٌ-;`ES3㒥a,BDN^yңዙ-s\UvQφǯ=Ic)c38$n3B:NӝH=B%`ObY[X 3B#95yHbjo IEGar b % eW$YcXxmC(uʎ%D,qmԤ-esh`Eb2VavXBF/M? |#sCzŮwBq?dc 0eI̤N\N(d?Θ_Sn)#.m 224 g Ξw=;vC+EibP2zv@n)bőQ,}' 1oI}5E ;xd m9m̨*\,5kve]8M$ K*_ߒPtm=ihkJiIxxLbZm,. p(Y vQ*<<&qZEt"!ɛ1=ޑU8OHxa\ a-ԚΚGI^\#$oOB󺕎9>n =c j$ DzLWevml~H2K(R}XIMx $,Ibi=06Kd^_9rkD P(s~ށ\Dʽ:;VqO@d5"[ 'ʣY<+2Mec^bQu>Nr @cP:@'K>R ,ݳ/Ti_UIDY[Պϑ<]߆ oueʐ5pNisbkA\lSpM:/|u`nuh=:ʠWz=UB@ 仝zoR|MCgB7'ui"9"ODE䀈mxRlLf;翠uE%"cu~ KDdhcD[WDypSˤn㶞`'^?H !0&F"%=2pXަm[z~Qv-oҨia[y=', A-R !Gsk`FE ;$DL$cT]S "2uI>|xZHƬ" ,Ot[ ־->$l-ϒOCj10I*g;n657[6-`oo%#ZU)=~(;14fy$l%UrHo["lv_C!`}D!fq H$ɻ6QL,ik=~]xo-bMsx*a " cW_/;-f? ෤ʒmY$D? FmD̒Xo~ߛMW5)& w] I!Dm3*<(Oks.Θ,31_&\O/|#qeSH#dHH9Ddv yZqHKbcGkskD"ZE@Imu$7"|.kPImDVD'Ry$_o6{2>>{H`1Zio`o8@:7+0iqJFQ ^yx5MԸG]î??u/IRW'$-fB>kzKoOKQGw1YקKubZ8 |/Ān=ߟj=6{|6NY9iw5y,^.uȏ)mԬ6 =!;D> vI\$n\͔DܯK\,MBF Ev,!&ħI~`k-`K;צ;51U!j~~H0k{{{&pmi[.&B烼>tx: v$A gKw; -qfoyԿM 40 {V 8dد'MH6ZW/瑀ؓ1uSW&|;到nUrĢ"2 B6AH|`?_LG'>4ň>qX}ga`~`2?%W>$8R") IwIWKNދ{xU1߼os\QM2o I_8/X)n5IENDB`ukui-biometric-auth/images/FingerPrint/18.png0000644000175000017500000000640114064326115020022 0ustar fengfengPNG  IHDRbb IDATxMeGw3_'&((3f#JPW3u1FwE'E7  :4ҝDBgb33UzU{?\޻֫{uΩ:UuH:&霤2{;)c:ccϿc imr[ ;oNH:#ig۵eb}ޞ 8s] |z]*0,⩉Trn:,.tWIJvP0T!(GuʖWڴhS68LCbʶ`!B9/i#RWFSHP(XV.0ElVDxALș QXVC̉8zM.utڿ^gL#V̜P633 [俯܂>|װzeWIv W(EQ<7bLM;`wQ^Z;J#$()߳Hu4)GUAp'Vӏ-/sc͕\ q9);&;F+Ns'&iN"DF5YYW^+fb$AF]zėϼ59E\O\vLÀ܂7PKH:{rަ[r0۴8UnngRFD0N׵4SC3vuGq1L'ݱ-,hJkmߐIڎ/GZrڡ4uʱåu92=0Nx3Vqaٶ9v~Q.ToY-nS4 USɞSƏՆ?v䲟mCհwV ^Ey.10KSp?n"h42uYjw6yTsm)TBX1hjU.RM"QVs$m4Q3 TÝ57*~uBYQ{4bOTM#)Tm$K->,[k4(FѬׂ4 u+,aua!@ne!0K*ׁAo-FtХ~]1M" 8\ޱ\mpΐ޵# Y;6wZĽK9"1S y4ssxx| W sqhoݪ[B@f-?M} B&}eϜ'zߺ7g}z1qak4'p}NӴ]X[h "Ÿ×S7ZeO }jc!MO e4iܠ"|wsÉK>6Fk3}qS gcmScWb&DiJq$k^=mԈȌVH.W$M#9 uTEئ[79TY}ݢȩpxth6Dz:mu_-49lG@ Ǟ贳hC2r֯vE 7u*ǭE>sr`rj82kPeI/6TsǔqL՝EuRCPqOf[c<1yu$k'*+rӝgZoB Zk!ujr-"&\ktZPfL=K^G6= /Ni-7E J(Ug`70)%BpN!]OV_􏀟QЕKB|g> o'u "x(@!..biLF0px/Ug%%>+9nGpTGLL.r7G!~pj_g7:}[8_pTGu.\T5&chȖ!䉈I 머q-ஒwl[WuI8- 댒2C#-ߤqrmMD¶)I`B>qNK㏿ey16p_IHFl7c,"< (GK\l,!>>z׫yxOw {qtԗ} d0-[>i"HObMV.Ӕރsր_Q}6TI`7 7Zf"[2*sdt"`IH}nҚ$Ju|AZ;k[f".wML&;f D㴉&8'nqL;Z|CpɋNt3jF[rimvPa[vlzRZ#89#VH%ܸʽ//&ܒY[~~JG5 -"|˷0x4Q|NcR WX3bc{D#>)16CmܦZݦ kQcp%ُ.9qz "n3i/R>u6΍mEX񂲄( u#5w!JDP5MGpa| vnĜ ]f$pqMEl(<6)q#6kw*XkW5{8VQnk[ ʲCZd53|5reַht{R|}^W4.߭tAz=rxQ; . j \PΔIENDB`ukui-biometric-auth/images/FingerPrint/09.png0000644000175000017500000000705314064326115020026 0ustar fengfengPNG  IHDRbb IDATx_W?gwIY61iDڤALbUD_| } ETA XlAll)64%-4)9ܹ ̝;̙s"KD ۪"r9\]E 5?@DNBnGoNAгY~D$񛎃 uqmܺMAD]}d6ݱk?DDB鎭GHUƎUx^;"D}ﶭv3]d/n>U/qD(:N5#Dd :ڿd[d#OUQ۠Zu5ir.? ioLGAqWhkKY֯ U+j'nzO_fvt5 @y,4lkY4,YqyǕB|'D 8|7>m';{߷~}IQm0j%* vՌ>[ˤtC|'[td!` q52-q]DFeD\&gpQM('|-t.Vt;{Qh|Lπ?f̕䑑>GNo4Wmx*HH_;^cbRvNFBU2g} 6CַZg"" ₿5IC)?,K0i^5wHIps) ?wGeKs2t2'bLq)C uEx{ι mi'mhT>!:>ZEdvtF0ߊq"ƀo . ߵH3b3И%w5s7tYITk|~GhkT|QXy&+>~MflN3 xpst~#~ 6_GC9^c2ZoGF%EI.iըA3pbŠ#"2ZO.tnڻGOkrGnއD"ef-cGůC=LFBLKv~cnLFlS!UT7%v v< MމfOR-WO"##7 Nj#;% k h16<2b!$C^. ڂw2'o>Vm8{y׃de%I8hBلݾh&?!k3-wC46Z +&f,lM]x -Gdl.<'_o#,7s19)PyX6X[lf+~l|,אx^E v2'r\D&E/zN7v] ӨޮwH]D窷C AVkv6ɦ ܎{=ImQ g駈L|֮f]kg"X&FEdшk z^/B^ekk75y!c&ldRr|}J,Z/%cS$}H1K1|DԴaBsHUoܴ!"㨰zN /9T }˴@?eedEө6X\FP CI+l%Q(+5CψrN/M-wMwe cYxW4͠-uÒIm} !~Ĵpo4ƈ&F0is}dt_\v vstZĹv\S ! JBi(jĹ6A۾Fk-+jD//25-'5ŘFwMh -4MӨ)FW_TRa>*OJ̗-g+}YJ+E_LP,]O==vP:-mMG,C GNKe+"(D3h\m/~ݿ ܊FGt}&mbȀ[EdSw\wP8P.r˼kɾ5{h.u-uƜjۮzp-s(/g#ַmVWڈ1[w6~rT7HaTeR42j,`LSzͬ/UM,{x s_%"uӨlFx8i/";O8.5K!;vw¤QY{QBcخts-Qu;ٷNvKXa7J j.םeJ1`m䫸_)97A?JC_1,A=Jl3_e?ҕ&'j_TYO1&gee,Aa%|"4FD&P2]u5ADR86hx40'S!-/9}}MjmзD$$Tvv"񌺟"* =~*j(so},{yBmPn 14ډazm }?mkc!"ÉG溴nqG\ke]e~ȱFѡc<<"}k6D>^pXV# =WH)5_Z*&k~^U<*ɟ mK_CrIENDB`ukui-biometric-auth/images/FingerPrint/05.png0000644000175000017500000000702314064326115020017 0ustar fengfengPNG  IHDRbb IDATxϏG?Ńlpb @!qp  wr8p $$p(,Ll˫8z֏C͏|VzիpK"򖈼[]ܚAN&׷DRQ7fH0ŗ-@D>]@n7nuѻ}c!"T8y ;. %p븕"D'"}9."9)"t[쾓qM'"& "OCtPcm=w| no4i;wNCPBϦj"}`+%ZM}29 $&p$~`7m[r2zdd2: vl70b%JѱڹZL#D hɰ+U p^y>  OSH핔,&ljB}rR?d~߀Pߞ-̑A#)~j~ :'/[gC 9ժi _|ֈIĖۊ?k)!rIMc)Dϥ:I#nwH Qr^_~: '%0G Ygr#=M+bO&)Ytˀi75uY05}6S5㉭5ה#b@&tI%_k"unD$!C6YM?d:f;*m3%a@&l#¶"Bxzdx!!|xXAfL|Y5%$xUVqz]2&J5 ~o慜 i2&1jr$x$j5sy乻EdLz$x }UMQG=7+C"B25'a#*ZM^JJSt &:K)-Lsx˿OFF !WKITAfLJI[!< '!揽S`7=y, ?Q0.驐N6pArxr'~w.mm!ch]ͮ{s(!gFDZDNv8 '$ۧN;|;L :fTUkV㍰'\;㯉}'zΎ3M13ig1uzMT;&Tj!$Sy"ɾcOF^ \w}Tie1|Bx$"n$Q՝%kivagy,ΈD B9h8 2BF!'M]։PA\&k#~q£6ahU7"m!d}]"!KQuj.վuUSV#aDJFuUl h;IF+D$$I(}IYbM[}b-ߩ">i3UE OL]Fd>~ECbO2;>BB[qE?&]jBDI=N@bL<:/sX#BwJ@&=}5E2MaᐂЗ$}P4U&y%=OSU 6Te/ "WN.ڮMb-ua|2övͻ_NPPW"F;hVB#S. "Rٟ0XGľC78Bd2ͅCYGW=`Ԑ_ګ5bQ!ED\!Ji;;DPm?4 Zc4hjk]֭w !#U/ VS*X6QeoΓhFf[+ubpa/+";N !<u`("g4jEXTsH1qB87DyL9q"D,]Mb 7[Ӻ Cbqq:NhAuu plxYrBxĮșPn&EFkE^ws@lЮ[I0oSDe !Ȉh{& J6JD6:eyPuBvBc>S5^RB),4F>PZ3͑{!r kK>lVV=?30l& a.\r%V,`dqJ4ID]f '؄5U2T۠aP(LD E ]*JA)2%Y,z nRX"`6[Lr.K: xMDϻHftnsSݚ/te= z' u+qΌunufq1Q%tԽ_z׶Oت V{ W# NG+?j9מ/Y{;u;wI/w9"Z곃oc<QbZK7ݧ4.} ?dj*g`1CUq,.jW>nOxBjku͋#X _)X6~VڏX#A8Emc`9ҙ&oH{/4N 2QNQHEd0w%Di!:NVhGK3]E1ovWoc?C7eya2NAD;_7[GC+-' 7e~:G"Yq(k"r{lW"-"|:uۂÐuIENDB`ukui-biometric-auth/images/FingerPrint/02.png0000644000175000017500000000612314064326115020014 0ustar fengfengPNG  IHDRbb IDATx]AhZvЂ:k$ P ؗܤBC9عrsY| l  0A ,-dlFͬ_ΛRuutU+~_իW^U :_IH? l@ZmOҲ],[4p*nkcNrz(|FDg/|xC?Ä)/` Kq&UU҉fDK0}ɇ`>gf!a7!OJ [+HW Zo{'m'"1Lo|b^`[tKeD]8f^Wj&%SB5'OpG&=]`fY=aB .ʾ]QCi),k,9[ T'f!BF?~ Cbolx?%CcmX"Bw?)by#; D[o*^I3_SS)xIDm>Ϣ9"yc^pժDrqOXtB51: I|p&D02\ JJ8M)ހU}8|91ETY"DlŁ&":n!pd#L=":Yt5ϕ LTP߆#F ΣyV ؇#e#>U` dg`A.zy/ȗ;a5g.|^9[5|&&&y+:Yh>) |s5[E))%\_a1ޞ%Y0n U`6:s[Q*Xf>O)D|9נQ^ͣ*kF*]!N@}fSd爡u"du9])Y8akquhwR?86s5b⊛uh(@RM:1Sȥptn{p#uuS5WyqMP|L٩>:$P|n r)s׶0=u~U+ QcUΙb"Dqx5x71 UnM֭2&;+t/68scXӷ6(E7Anbb`!c,r&:@ĸˏ&W/MGM YQ|P ,d\ߺc(n5 Q>d.ޙmʂ ""_i"Lcb Dcgru ۫fRvtS rkD3o:Ifoko 14y{.ᖡkt /Pk|PYTkqRp 3U(#?r+yو0;k@K5p½&!|LyuvZ1&$+]"B1ӽ^LJ6}ULCT*g2Dƺ2Bs-saR72S[ٿ99"LZ@~RRd 1 Ԃ?¤V 0Hn|?L:3ʼ 9H͈eϵ;@]rVSj1{%U(FDSI 5GjLuBE 5=u}:tiķJͱq)&6ĶADx$$ycۏ)ޣ2?S! %Hnȳt K3W] }`VWɟ'Ta+}D\̳k̿3_7郢u_׃g'`ᐂ} WqxBmU7̟pg~΀A^2{ݚ!IENDB`ukui-biometric-auth/images/FingerPrint/16.png0000644000175000017500000000653214064326115020025 0ustar fengfengPNG  IHDRbb !IDATx[$W53;$;KqD-QL#]AaATQ&B7A"Dmi0n 0Ht ;7\>w>s=8ꩪS.V"r@DNȒXdBD+*pB!V#!䒈mBDUKF'Ic u@ 6n "dolܡ+ "TDD IFxO5]P_3I\g}#B\|}hi~PSr2ph'I@*YnB{U'eC_F|ZqM!I[=^-ӢMപ3i#p҈)Raj!"iKzt$E(${HbQjĖE c^|E߈gOSWCȩЉӗe:fPbDC4e l];uD 44lؘ#fcX%{InC?mwAGCcea4BD%IFV>jcU ø^wVǯǧ\Os%.8єojzKC4'^Fl_5(C= !KjBa+F"xm w^N=<.ڏ[eg$ch=`ue"r77{xܦ[ NٛeZt#AG.ƮgP]#MhGZ}T<I,SIsG¼&,ֶqԑ~l޿h.ŊS} [ 4^aBzvi hCK˞2/{bEם,0ibP2r_@[CFqDǐX aG@\߈ڏRod l.96ˤ}V!xGFUa` 7To7&Hosv~^PdwĀ[ACؼd#M#oHw@TT RaaXBҝ1joR_xYF2a`j g}2nYBݓvV`^Sic 309sl t)پ @$g"R ifHLs#_P< [*M#)T)$J÷x`l^/ gg:VT`P"\Dm0U qi#oHjr_roV E%MF>CA:4o\d-B h ]R 蟙yJN" _\\mpߵ#̹ Y wJȽ YEw.y1y 4-ryqMVVeA[xP))'|?*::/vܗP~D[ך&Dݧy;~@mR34Eۅ% DZN\oѽԈ}#-eiؠ"4lx_䒖킢hX`>qRp<%{';C!BՎ#!8"s9-OPUe.ɇtH ǻ M7orkuFN%ϛ"KQAc᫅lr9 je뱫svvmI:뗻"Dϫ]#::dIDdRDDdLu"s="7翧LkSZfϘ#e|Mt =J* M׿VN/7bҦlz]""Sf$qu ;jxKo&In 5Wl'FefM{"M%hX|[GDxx w_8L?i&;@gyK3zIׁ4"Dd')`rcd )|g)&z) k &{p!%MAa$Ho1e܊WY$kImB!!1rȘ9g#F'{p{r$l1e|6L&|4cYM}A[xl5Ò5ླྀZ\& .!%In㢹/44qMm &"$jE\ |Fq%%0_? %%IIQ-_s.kzNlxBp{Tvցx"MqI}?W3BYo|&ax5o7BmɓuU_-PI)Kׄs#IMVM?jʰ$z[wmw?#be|G9K|k>\8\mɸ~/UU/8 <<3}1'IymzZ;$dt/"KBb_qḟ qG/:z$lnk 眭y)ylۿe]k Pl}t;}yPEyx8v MMo=8 پCZǼi ΓorbʯF~[͈vE@*A{2u]8"#4tސMMs8B79 8lEl[*Z{T Po2.acI~ f\_8b.qi\^ͯ3gcO?co/I@_:a/v6Mڈ5ZϳJ'JDЗ/k~I/M=S֦>o2/[Lwc艌Dq>Dn~ -$?&sΓe̚ڞ=8oPzӔk6UDK.HXEW 94pc$?D\ p!IMÅ3 FIƈ Հ7f5I~.IKն:Ƃ%@Z,(c7d1e<=J1D,n^x&w121D( wLKI82qڵg^C h DK鶦Al0j2?c?%S>$8R"SqE٩_h_4^/ë]6 ; ]ͻ>!ݻ߱?u:IENDB`ukui-biometric-auth/images/FingerVein.png0000644000175000017500000004203414064326115017401 0ustar fengfengPNG  IHDRg- pHYs.#.#x?v8(iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2018-06-22T10:02:14+08:00 2018-07-02T11:02:17+08:00 2018-07-02T11:02:17+08:00 image/png 3 xmp.iid:105d8a11-238c-4346-b82a-5ee9136f7d21 xmp.did:105d8a11-238c-4346-b82a-5ee9136f7d21 xmp.did:105d8a11-238c-4346-b82a-5ee9136f7d21 created xmp.iid:105d8a11-238c-4346-b82a-5ee9136f7d21 2018-06-22T10:02:14+08:00 Adobe Photoshop CC 2017 (Windows) 1 3000000/10000 3000000/10000 2 65535 160 160 Ro cHRMz%u0`:o_F nIDATx읿o #I'/ҤX[ cMA+m1M 4)k4V%@ᔩ6ik#&v+UaTNK/H")*,4{ϣPz8=u `y<3g|`$pE^ ^XX8K6 tcgq&s)IIWTgF `Xa_p5.xJB:o&.=|rp[ Tn~#ؼL 9Y}K S8+hR%r;)|aIoq `sxwMΫp&;@7\f\eB?SW)-F(yBؚڿ&鄗0g,;kM㤸ᗦWG>䨂NW=q-GR< oܝ uU3kF;UH.n|N[): t%g$Koԅw`.9`ZxRJ$X7ռؐ%T.N99>Q U/>P±D.e-,1S+6Y~O{<}p63B!V~&]_G˅5| `WA]TplLh!#װ.Tj 7Sdž4L.$l23-i܌H&ӛ.w8jESljO~}l/~A$u!gtňN cZ8T*$+~q* BsBmL^\7`xmxPP'ņn€!kw_>% ={ mԶ0y'1G)_x q1CmĕY&\gG147<%5¾V-Op7eI#Cf )=w26Z}1Ow< ¬nJfMO4-xR``qk-Qi^Ňrs ym[\)zUP|]cp¶94sf8_dڥs]C9 cz?`!(>$^i (sWD竤Hx1N8` 2+*Y ne_⃡S|0ڊ^XwK \NC/,~S{ H-/FE 0wWk?2F?2&;`ͯ-Թۏ5ϝ#\0tT?0wpmse)><ܶ0PrBa"Yȇr}$eK$ aOEN2,ʋ7`X&YF> `eGgX&9@dX&{.rayB8+EEC@xYJ6,'@2SR]鎥 NJyP JS4\TKrAUt,x0.}Zѣ)Ry$W37; W1M,ax;)7  A]pvL䂪"AslwL_ P P:gaBS^N17$JKDX&9O `DXZc AU_#yA$F?&Cf+YI `ek4A$eiߨHu lT${);k) ^DW٨U~N1- nӱ 0-r3eQA]4Ri N C?"̨q|.ɪpTBgPoy+S6r3/EѰ B4ʜ1"oG0a4/C~ B:,np%l1Qʃ=d옦`UWS1ðdz `-3R)HQ"E)HQtVjMIENDB`ukui-biometric-auth/images/Iris.png0000644000175000017500000005014314064326115016253 0ustar fengfengPNG  IHDRg- pHYs.#.#x?v9iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2018-06-22T10:02:14+08:00 2018-07-02T11:06:22+08:00 2018-07-02T11:06:22+08:00 image/png 3 xmp.iid:b78bea26-9a1f-5a40-aa24-3f1baf8c43a2 adobe:docid:photoshop:e1fcfd40-7da4-11e8-92f2-d9e6550a8a6d xmp.did:26e0b17b-aa01-6343-8adb-ad9cb203136d created xmp.iid:26e0b17b-aa01-6343-8adb-ad9cb203136d 2018-06-22T10:02:14+08:00 Adobe Photoshop CC 2017 (Windows) saved xmp.iid:b78bea26-9a1f-5a40-aa24-3f1baf8c43a2 2018-07-02T11:06:22+08:00 Adobe Photoshop CC 2017 (Windows) / 1 3000000/10000 3000000/10000 2 65535 160 160 eN cHRMz%u0`:o_FIDATx]#yBkj_lW&E` Z-ugi @n,EH`\&`B#Tx= +!b+/BsF;;_JGs4?QYeYR5AeUVVY`eFI@xRҏiSt_vYgJ!T;ܞJݢ'G N<`vtg9rh4L}oI[ ¬Fl_[Fk>h  x|AU[VTmPEC򆋍BGPYLGT^/Eb:TT68ૼ\mx;ZZ ۜ =n[0"PN 5G va9S !,J|he|6J7xPeu EneTOTUFp4yjP'+ ![X/I񄊄P+ m]'4siv_) d=$ n48Eh@ivڭn8K_1x  ZUY}[B2cE@Ѱ>bU&Bnj(/;IfVR2*mP$kc}FE.zGzOohP e3N,·U=j$az0 }H:&AքJ2Q6# mJP_Bfq$W,iGW5KlNh͇@ni רv's 5X#4P*N x}qsԥh8flFЎ~0cQW߹n5H-ed7.ݹ2̼iN("*Cgz=Kv3fN[daܚt+7 il`}H)*'dRBfĊZ7]z5l`d}OHPŧ*ϥYp&Y)r ]wttlY]DĽ{ajXMNPy|(gTCj@"3 SOQRtr tgVìA:h 1>]@OHA l+%Gڨt ɏ~6C]Шt<&bU ͇ {^y@~jLh<eKݢe +4]mZᒌ59CԀq>7aYɰAU=Skx3>޻އ[S};$g˜y}":>_*pH(|k)o0(x xUF)㮜vKQ鶈3qo7 |d}kRP7|S_jT|T<z"0칾 vp Hѽeڭqv=/8qWnKDdP|A9Xmu~M;Y%නEBDϐ ڞ:dw裏b_AeAE1鮄j=rB%$*qѕqoc-3\1y'O c^/ؔ8{7)Jg_tn=.'Nמcj{L* Tks/lg2.zt |{Ss%|5ȀV<xv ODž/ŏ a-dwZey-_?7eˢDerwکx/$C#tӆ闯O}ie4BQ 'I><SF 3f-AEOUք !V uk!껴_8}}U ^x<+#@1޺` #꾽~7$\әfǁӛ6d;ZO0m&l (Y( m 黻~sϾ 1ևϞo\M?0/X_փ %od"I2l '/ÞˑOٯ?g̾쵸d*-k #{@y_+|oSۏ=s ]\xF_KWɟuqyʱG돰tXjoߔ~z ,N3P`~ nz*SiBMΦ͇Ա[d qf7 _ @, ؑLz~L@˛,Ύ2K8, o4f3/VqѶM!=dbwP `AM2 /0| }Y9pLJ0>g΢W$-ƍu ? 3~1~ұw u5NdVBx4 $0%8ޒ̏?ɤ_w 1AT2/,z%49 y]S_u5/ܿM;U>+jQ?Mg4kU"gElMXc4 tc]E<"JHjQQ@x[%MR;oMy̢닀/2! ° |T_&'Fx{O-? YiXݛ,$} G*E$&klAx{}K~4W'{DӵM{$`酋Y+׸:_jc*笭K- !gOb8p <# x7 Y[z1d,D&8Tcnyqzx@װ31@2?2HIDĊv`b57I/NZ[4?qdO]1t kE0p1]sIb8dh*eAQ郈Pcfi^Tty:&yQd5k8>aw͐ײy^BvG8di&CřR .UBR.|2=WmPiX?gSZ6'˝,R4` qZPO#,ZCC<3o}(]G.RG݌xYP粒II!]ݱtY? y(>Aރ j$/mf#Zj!>!`g&s M8CE3љ5&@en-mEBL8D6@W/5Ԡ/t6B\R6}3h=6ufPNc8ON nޫ>r_&x3Ԗ0O4NKp48fw;햙QqТk-1aS:@ 0tڭa5|#7 D9?M,v'Fĺ¨ :&Ä%%2 VsDR($żr:VS'SFi,!LqYٵREjxRЛ8h @W4I:?AnI<{' ܑa, iӜWsEf.R׾'+ ` R UxF $ຮK>~He&/|B(o">=HZVRe!5'?cpMvf7'tڭ~% '&vڭnNtNK,那(ݹ3xi3O#?Tp%$SՃUVvDyn'M'']ǂ}Q1a3Gmp8oB/ rݲب YئE0Y+Dj уKݼBU;p[ )>lX}h<^V:k4` "3,NE.֗N`+ix¼P>a)6A[AX:dT5M҄o_wi -OXae T1 U))x5wB T&V[z57ʲ%| Ǭn҅4K%3z!C*9I9:1h%AhUHi[eu'L \ݱ,LɐZ_yC!Ys&=ata wp;V `.6'^j%V[>V;Bn. SӪd_ +Cj`U+}trysQ`Qxi3f Hvct5N)4ey2IqEynmG͊  `D]*v}k.$)1@W]NUnJJݚlsXHj4}v&5+x ΕA zJ@OxV0G-=Ie+9* XYeUVVYv%~IENDB`ukui-biometric-auth/images/Iris/0000755000175000017500000000000014064326115015542 5ustar fengfengukui-biometric-auth/images/Iris/08.png0000644000175000017500000000726214064326115016506 0ustar fengfengPNG  IHDRbbyIDATxoG?븩I))I RR( įDxAȩH  %Bwڇ &UQ#MihH+=<ٹNݝ=39?.\u\@D"27`9fT#"u "KDDdN?@ybLȮAshG>Z1^("[US B RBDX*o)Ȥ߀B%G=Jb5df]+9.%djǠe*D ֗DNGeND&-S/^:mzȆӂ"3X&$]$~Gy]CɘfDhxC@;h̔dk!2S$KM9vVY|v Q¶W7 ƂD{ιv*`P9/>볺gyS}@-`7p9N ;I5pR{T:i-kfU"Cj?j5I=6Ҕ.f̹QEd&Z)Yړ0Lj`rRJf:ŏu[s҇[wn,PWS/m^:-R=%d7R= S§ HL!*Rě9B@H8ؔH@*6ҤϻZݥqF" g~Ri5sfwıʩc y̑ƎMMxJB{y<:83p$۳!?7\b$"&'YCw/Cκ1q]O0'5+|ɲDdTD6Șluo6빛4ؤl&4q+:LAAݜ'[O~83a/:]Fv^5b jWι?$vdD9-F=|ߘdp&!48 ("!,> x9'$ >eqOtnɫfA#nŧ' "FЖ ܬ;W{ >ZƯO:{%^r}! f8|UwO7t[DOq [YZYRWOjw52 )#N'9׎WZȻRDh~$( ߐ CIh[V x$XVwrG_ˊsnU? h",zpw T"K2!c| |obʒ^Ho;OߝkG[AS Ϙb^ƷD1cZɛ=w(GBX&2}5_v:Hˈ) u yd'%6#Ո@~@PyXD}@!]1#p'OB?z2'(&E, CȈA?~'㤒 oDDQLY"m{l`7#|(tD: 1 0kdRd4Q)R"_$OD)%~c2^[eD#zX7gi$6\L~4piٔXbbM]ZV?H6\&k|7]G'!5"8ᐒz512;~biJXo; ?LS3,nS92x2> gES6`;i ᖵٱCٷTAcW}3o;㔓fќs ]v,\I9J:HPmLmע퀠M@KX |oQ!;-x3RR)}#aq iN:f.l1A"& IHVRuiˤk:`ȁQDdmoٶE`8&1R6ۦ*R|]R){N0xlvp|CD>KctT1iV|үU9[7ɲY_e&k~=ήɝ#"Lُ9كLjɛGGLYrlYaj4jU%JлGCP\ŏioZv`Ff=u\/<{zܹ[zsb4|n92KR7sWi^bıfI5 ~tfB/@ńY $ AJNKTxkeȈBƸh1U2b3Uv5oλ9e/s ^ܶ6h,ޔ(ZHe^*1FȰ*B#e~vS"lY8_R9%FS;KNzͳTXvr9iG;wp9lw_|.M!F"?`ձשo%3)Ozv|K1M/&mMV)3WMNݼPƯL{ڭc1MXU6ܵ+7T%ْ!kut@lgɆ&"YigyØ %ιO*w7d4?K>%C;Tq.4q>2 ֠r:xbVÇk֑&UTC;UrDd6H~EǷ0q*]v}pc&suHF$W_Ȏ JvЩ!mO:P׉PM~ %!jӘ{H+|+IfKv;zq-krv2yG8r!S|8{GB쥊5sFBD2mi2uL^'AßМZ,!m OH<BڗMm#̃yM¯(`9Xe h$Ȉ0OӇp4nI (ݰmFK>ńט+5|c9yTVƢ(Mf,CD(=j8YӇS3 _v*MeH GI}zC݂f#L^c=* tݤ#[* ${V^h/Ȓea:ko* Q3zy00#x{:CɿﯿvA}ij o.GBX29Y~iF T>B/=5 Ŀ!9a{m<F"@v< kT}O.C fhf U^csޣB!}}0"~3T'mC"3j;" FBE=c gee ~aqQIENDB`ukui-biometric-auth/images/Iris/10.png0000644000175000017500000000704114064326115016472 0ustar fengfengPNG  IHDRbb IDATxMG;M%1J $a-.Hp؍P ( W N֑@‴Nɉ";(!$0D{sW5ݳ===_juOOWիUuM ]@qI%-Yy㤤Ôe`t@ҬEqd򤘕t`V3I/U U %69.25LELaN';7Vig6JJNȿqf(Kl!]IpBW2[ǰe*El,3D.'ڲ(iz2՛P# tVPS١ 2D$jd w2 DmqrP_1?0HpC)`ܔ;!qSMME5=,?;yDžuWMȃTK] /Gιg{19^;Ks <% 0{N:B2 6 Z/hyMڭZ]$+[~(sI}5ҬsuQfE2U/T% 3gi9yVřNΔ\r .4,PћTSWm.˞2RԾx!ev{6%EyFCƌR暖I|27u@͕!C!tAf#Ukixվz#WeͿyCO۽j_VP#NPδ!{R֑N-Z7t*iy::]\IPgr!hQ޴hȽPnS"{&J4Sb-gmvj_X@|TT ׁi|@) SŨ^77>!ld2(tl\Wq ~j!Ο$Ke)i;/R6c*UxirGi%$k!=5G)2I깮+wщ}w%i|2 uBѰEaR.ě0_QK;U+H>q^Muw^HtQ5C]_(VjLe&"*ZeSWY~ެk2*(qzGc!zݕ,ʔ T`Gk*{ dJjv-y4.%iBҤ3I.#2~@d(uH|.X뚴1kII[%mS>d#^I{%= je$%MEzd,Bsq (Úq80fep/~,𓚲$%56pηےUཤN/-9c q% Z*|XhQNc~W{;$$DW(!Icιu 52N:q9a*N?=2?P0Y$I`Y p)ι猌sx=<ђoss6I-|L݉ ne$܊҄C*✋[ιg%3ق^Suj1 |sJ=uNI(M@Ċ'"Bb ZDkW,S:E"bˈIE85cE1a@x+ c\wߑDJ0Ipo_kIL\pO)9Cڱgq&NJ&.i8B~ @F*Yz,yDFx0GFBBEDz݁@-&Ϥ}!uvh]kHs>L5<U 'aBܱ 02ވ) עl/n5vy5$n@Bybm|ɓ6cIs/ê0=qBkrIS9tr&Y'/\ŏڷ-"p<[G"|#ăC~o@ƯH}ڒ' (QE2ny GMYX[Jy[@= O'*>_ZFWkyvmcwsmz޿o/¾IZ&K׀ڳPl֩;~mS&u2>,%¹ K{S}LQ>+7-uXgo#pqDRqt4|/+|FC-x*zn$]: ӘaǪW{=xwr߱ ESdQZ4+2  I#1{tY1+o7po"YcdVϴ͸m@~ y;K7ay,irTzwCV3k岉. 2fI^;Vsz|:V^IEu=5Q)X~x9wNN`9"ku[/j*s#av Yuun{ oU R.uq6o r-ה6n}'*j)$nKJ&虈) GrsR)#^b$W+U:h(Vګq%aT02eLf8 XD@bnoj%S/ 8ff׼$\>J~ zLNYH{8蜫$_BrM{Jn .9>WLaS6d]Qq v]Ϟz& ,RND MF#d/-׫9%zӖM져oXW%gsO=ױ5NsmJ8˻\cĘk<4o,\R@}_ibd%[7TU#ilo,:QGQ:.BDp2j md ᧚ : ^NUY]'Lk>ѢALx͹-:,/-ZӃ]zۺY~Q!]N@# ^-y b& tF7 41(K!b2># *P6;Ta70 w 4jۦ*cf7+haEoc}4hpZ2sʇxƌ#G@voPUYڇ}֠,f/ .mQφ,ˑMU ?شn!!w3zIENDB`ukui-biometric-auth/images/Iris/07.png0000644000175000017500000000745014064326115016504 0ustar fengfengPNG  IHDRbbIDATxk]U{f:}ڑJ, QC/-D?藶ch >M &'3 &iKB@k+0C 函vϺ{ιw{}Ls^ksρyc=,"Ddrwn1ȰȄTc}1""ݐoKZ("U9llBDSYhʛ٨7`\iZɝ9ϝ1D1r6hZ؜pW"a %dZGe*D4-3NDhz#mݖio^e4䬳"`XF&HΓ$LI/dÒםdu2"wԻ!\ 7%|+!rS퉦$mKg RW\,ly1|x%\pp 9VloTD'u}\$t騠9vkMι_rm7Fkm[նжg. NZS˨YO97tHE5iJ% SGtبx(3s 炶[ҁ[FIGmg5usj7X%uTf?ƺ,K(ɞ҅hL ) el$s% Q7uA-B/B¶$6JDȀ,AY$",Sqz~qQ]Jp̽2鍪H zvРv9"Lx2$" Y)"Z.SsW赆KEeُLHХB~+$V"21ہ@̾ }p `{ ^`P_ڴܖ,Bx?,9Uwn?~롣-y% rڊUP, 3 |E{ x,+ ?rݟA h qVcoc~|߁Ѳ2vٗBBwCϽ_+{X|ߴa )}U -!}f׀o;r o~ JFR+dE%0e 0wGp]}z$ps=Vm1! x "` 0pzdq"&#nGH.z^=! w:IM!~0 `ߑa9|{/{f[L_JFYA6}GER OǁL>0']Jf f=X2IaIcH?idѺ^cZY:?&\|GgT[)<'zgS9k5 & ` <q2k+e`/>|j"RHZYt_ ?AyoGS###< :5&apvw,a=;E)*PYcfL o~-w? I{(sROzIQ20gO/u"`)KtyT-j#|gn'l̵µC F#BӾv,7]+"{ui%< ~>W֓7:'o]m!8wM"ZnEtF|ZmBB68jER->PK:\oY.6[MoοLͺ] 9[\o.AM(>+e `-Kx .gv32 | Os*EG{YqCIZGۗcǔpW+t|jY.6^d@D 6x_H(ךK!k\+[׈?V;V0x%XYּm;c/g dHM3,LFS)q!?E UmEz^mLb=}B|}yz`ΞS!_!ǎW!|x}Tȕu4> !j?/Ŀߍנkq~_\ESEfء+X8%osny 3># $㣜A~^ {&~J=v=L]Ttb|.2lϛ+vN) &x61ktyTL934^ue킓U+A\ aܑאMA[mEL:aVWڒx)|{.tιg˨A OBPX4sϑ=;$"KD>mme}q 8;ۅUf}OZ3Jq7R:f} xH:o B&iskZEb|>8ͬuVpE2kU4.E;Zΐp9Y?Ȟ(0l=vNnC$wJMHrT56n ݩaih$<dj ,l\C35&$-XFqK9 k&0w@g\vKj " 5574D툩lTsL2MYkΘKԸ1dh '*5PG#8:jl9%CBUHԹUdn*5Ϙ4L<''nȴakPxM )7: "(FO "tBVWISDdل^8ri Mʆ2vsG,&:r;ihTD.&&$w~sS">Lb$"KSCG^5YO\c)マp@#cK3ϾdԬT]պ9&;L繹V_uu`ʸ2%mcOd`50U 2VwnN;%n[#UЄmYƀ|r'Kq-u˨r]AudԴ5EQ=N$>vb^AՅ.N_בYx 1]?>\ijhgfM 2k:R5è gK*:|Zjk >S/~iD@U2Y2J3^NR"J%fChV) |H*5dY*xwl.hYuoݒGf.uks4[^B|bNbʂw%3c%7v;ޔwLEHR^ wل@ S-ʴzLe!Ƣwx"b^`}O ~v8^鑥w 2buIswWs0oZpz"w0e&QP,zj>nWdQƻKwZ,+Kx~|g?!XqQ{J!"\$ԷߡaV` 40a`IJQ?t4S7Ƶ,0T@tdodA H^WDokKsFYU/%zuC˜t=8T9;[_1H7:c 9BX2^qcFGUa:~9ΞhwOg a<O)egYAo|,?{/6ρʇ |w͙֡X74VPS9G2ףB!@X/")n(eSf6]C"7j" FًvDB^.6vK@OuYg@|q&<s A$IENDB`ukui-biometric-auth/images/Iris/15.png0000644000175000017500000000661714064326115016507 0ustar fengfengPNG  IHDRbb VIDATx][Izf2ݸquAʼnD'DeN""슂ETf ,^,+>""8Y Gm&|Sӧ/L@=]U;uΩSii - $Ĉ#?$g$^7ޒYѫ<,|lYꓷNn853c7(",n̒džH'{A/z w"똎 dCώy*$c v4$#h[S5ӍH.8)g0$d͂"ciOF4鑌<fE5lx=fQG@"QSL17:*"M1 m=B *E'o:)!Ii([DT83Io`}{Dg,\I䑉2H4EN6MC,=6%u-OZJ_H6knHQIc ҀnʱcAL *U&@*lnV.32IY3i l*!Ӆf vzͶ |kcldz+fo$r=xcyb>'3Aaб!:շQg'XZc:Ob HiyWoߝLG.]O_{ ̧Ռ UC>9ꉩ!m %.@A){Ag.>$lM^ S,P9Fn/Yc"yuӠ$u`I3?i>cy48ޝ1é`D=$DG_F͌X `ScY[P:fqL̯ 'fwItD:^xӈ))| U?Btdֆ(W: ~VRu78#|wNT2쀇PLu.HA9mĻV6 #DwdXj3ZBĬM+#άA T֒*)ìZ5L.<*ZTg:IaYQ ^zRWuoe3+Gg.aⅩ05Z{)wag W[pfh qլyyu=񂴝h Ք f= ƨ>4:z2VRTߘ5حm]E<]zm RԨ/%␢ufEwҩ2p)=p)WCzyF<$I2a iK3Jǽg%=֧fԁ'Tǻ x7X_[&fWⓠ(U3HgYw7 Q|s[BzsBg9GLWѡ_ԡuĚ/t,L}v=#b#0 4VUeT8Z`.fbupl接2>gfMjFNO EǾ]Q ƒ-` Y@[*4lG3@Z1ENr]R5K%;B;3m:30je]4nM26Vm6F@"ڠi%*0PL6__JvPm:m*xa{1`I#!ݗhGm濟،-ۘ`6h&u0wGklrXqg~6;q F3;e;ꚘUQoe&7fR΃QqG~|rvƧ cz ̆=gTWE[S?e* ]ߟ.UI&ܘ=()LgeA`RMtؼ75?[ۏ,0xR7h%9GyI>O[*A){@%YmLCD pTSrMhKt'HmU3Ÿ?' ຺Gݾ hԞ 쌨%IK]kp z2! A5@"dN^Syg$068b$'BJUlÀ$g o<(=7Xp' OHג$G8U(QĢTp:R͜|N>e+~` UTa7-wXpI7O  꼍HPD%SmWeTԹ$IhtA9AN"VP#~/~ip^)G~tm>$V0p3*v:DE)قǟoV* X *-/p;t*_x/fx} <1p4w+_1,gР̨7I*+ oT7V Ր9{ԽC(U[}'m@XP(RW/1/QgOS],g^G:E 虐|u=R@u&8c1tuYWk ڵB!}oqoO䉘y $q+pRe@).b@϶xǶiG3$(h |4j{.e~j]ĦohKC9OiS@2Pv5ټu|֞'{NYT`So5g=󲸧?Oݧ}ڧ)j}\F9KIENDB`ukui-biometric-auth/images/Iris/17.png0000644000175000017500000000640514064326115016504 0ustar fengfengPNG  IHDRbb IDATx]M]Itgf3 8 & At+tPЎ.w Pq r!2[_ "Й qzAQ|=:sQNխ$.V:[ <րH<$q1yHn\ҧ+#ҔNA*FBy1yH,vf]n܌~b4b8hE[\+; @f:)IA,8_fIڲ$;6O}R[0u4䱳I07&#hH a$`%CVM_W2w)$ :yQ7O6E7h7륂DŽKv=L3:ĥMI˫BC1&AbiQ!nEj[{\8.AU$>EqMaCgHbQ6CkCRnUBԶY4FK")*嘩wPCC碚etj/i=]!U2sC3t)PMK0%^=ty fBMzͺwˋl=)11|e5Ots:|vb# d;0 .߼;˫7u] ~wm,yV yM\DHC~c FW(sADڳ4>$̃\ }&.'ЬˠKJ$τms\UIU g65NԳ(F_+H4R各(Rk%+}ąя¥cCN$ ]?dw/G'Et#dlPV#JPCd$hJWJ}qWxgD)x UQ0"$Ai堂EƴbK}: Dc]q+ yokXE'eZ¤[<@vQlj٦N:Y~vVQlߣ6[%O_k;Gg)aNuB6mﬣi5[ph qj漺ܺSdA:N4 }M^4AʙK+<Ք _~c, *]H9]PRVֱ.ƕpmRlCVی%:Q[* י,_[C/Ua(Y.aP^ʫd LhkEQ20ok+钞_H$ku;qkxXҲ6q~003kMwTq`+\9_[zYYV5(wO;\g/}fY#|p\籄&#.p=ٚ#u_ԡ~ľ},Pȃ`vs^ESt6W/+sRv{;>gfp!U0j7&r({~n%K.32%LջM?_ PZQ )ZT^=wM?qi4pɎ.0~FFFAMܲ~r^݂1UԚXل jhwow$ L?jb;:Tuåe倡Oi(AĴE=ڝfo<RVjGU]aYڴwT!otuM]oV2÷r;l+5>M"Nf = d j]ZOa9@+]뷛G5o1,VU ]rݾ*rZ @fjo?bJ@kQdt!jN M,[f".(T"ƬA3n=-vn\W4.zIZ#$l[⩫lB,egƙfKHJ ,yHv5Ҝn?&hSVi4cOq߱%@{˿ܾ1):Ywz<kŮ^E碖]m]99n E)xf}Ңw4:[jxs@6ψn;EQ|§YPAt^VUb^$ $/$E܊>)em xZZ xMIN`COlgυkࡺ(GEQ<*Վ)Lq ε5C]4C4 o)0Y>IS{_Er(]/abh 0)㭪ϽHZA؀#vXhmf!>&0%Xj+0^.;oVV詳ÞCkn,G 3&[-ш#0rNU#lGNW|EkmSC`o"?#<Clj) ꀠ-S/OH? IQi@#"yFM-y +~#MVaA׹`m`\%|u8@֓d`m'Mma5O іͬe45Ίb hKxOʟsr.UVHMW-8a_WCCAeH),'g`2 w{"ZG| ~g ڒ6`h*|`wO|ā8='vd^|\4wRbcX >(*_Ľ!*0rG_cA~)0Tcy xWq?֔?:Lʙ[}xE~3<`#i KgPg#B \go#.'&A^[Ft,Bǀ>t t _e} ^ ߏU@ljq*eF ޖ]DN l]?}g0gT XC8c&ċa ]f'h7dljʀ1,bi*y{cb!B:FbAh)2&B #l෪}+r\5o{X*;~݇.榬uh^ݟT{;߭F;yrh iIENDB`ukui-biometric-auth/images/Iris/03.png0000644000175000017500000000753514064326115016504 0ustar fengfengPNG  IHDRbb$IDATx[]Wkf2icTv$55ŚI >ħV땢 >*(i}Ѵ,|kUD1 БĆL0LNuwY{/g$6rn7l`XE丈\p>^|<*"s˚ADn"rQqpqTDnD~-U+&*"2x>A}[׋ĩ4zoDGHDLȌlYIDnmˈ-ww>kZD܈8c 5f !s%Oa6Sw<'\3b p՜_5ܵ|Y`x9iFDM}L$ʞp^F RP0H@) yϜx 8{9ZCgDaq=}x9 dLST%#RkR? ڋ2MD>EIC-a_b[hyuaZ$܃DQU!#.G)[CιkU^DD$< |_(H(!eD!nq z9z8\ZP4P0c KTtKF\IP vw%sj*D-0|:iCF`X3`8LM` VBsK;+9EDd| _mSL6_uɰa@6$!!zwkgQ+} Dk)Muɰ!!$?EDVx2ǓUDȓ_Pp$.y$̏=^MUoc|[z)_*{/.3lbl"hϋIɆ)B~F$^1Ͼ°U oH90M˾*El_H"0j!(f7|f7i+ԭ+/6?3zlUR GT_3r .!=)a$BD#j%ęYK6XBv+|C`xpAS~ñe|(ks^)R5Ӟ& Iۦ{؍*t 8[;/ub}$>%OZ[K'͇5u>]% o^PR^M% oR4꨻ x>t X IΧ ~ Լ/nT?YTpWG E%bGS_sۦS3O]ڷ0+3]IDw {=(|wE?-+8υvb[Lc$BDv{hܤrPov3%xBVǕqM= ""7d$+eޝɝ81i4Y34zϻ( 0i$"[;iN"T-枉 ";Z ;>˧sCW)|sնiw GᬇH˺/kkSv$(/U%6 R9}mIZШ(; !ᾅi* sjjfBh^-G^gZ%=QUNQq660Qĩ2ڰSOp:xnEdn[>[q8.](*3ч)Bl7i/'mie✻,"іVisGU[]"f;,ЩuIBVTz Ggd%"aVsG[ՐwQ/W\4OA >J$AME CNBki/2ȮTh4?[G!")B&8\[һ2o[,1ZNDB/^3Fm2$`QLр +$e<С|y7ԔƷ6lԩfi"@ȩshhS JG ԂmS [@5ua) jEt͵b~S62Nѥ蜻fI*6K&0)R; YQx YMLR봄; 5@~`7:&#u:r J]0!\@p\jJܰtVՄuC~/B3"o9 Ac`Qrc\#ڙ ujgM]G1 H[>ti!#.!GN4WqM6GNH=9dنbvf @SJe|tdޤ_:"k:a=vV]k7/]hY o9̐<;ι{STJ8LJs?o45qD`=54[_I=|o"pkM1#e/ZѴu$bWXF,|%)Ǻʜ>,LbTgl|"=йG_)5I#wMThv|OƘW,S]}C0EI"|S"9|^VZuYk1MsQ}7xΚ6ƤX=K!:jҥ]0N&_T9o0H㹓&$r\9<sa М|pl ]0$"k5b9AF`. &R|5KxAIzm4! Kψ,x}BFf G'5 ~uQuk@DȤ4%qX7߈Oȃ&'"r ~غ0E{HuJ5Ck-(CB6GrGCcT;BT.P.Tʎ^'C"3j" FBE+bb! L*r401?7lp@S+a.\IENDB`ukui-biometric-auth/images/Iris/04.png0000644000175000017500000000742714064326115016505 0ustar fengfengPNG  IHDRbbIDATxˏ]G?iۍMll`p,HFi$lRɰ`mlX 1#X!!0#3,w'ƑiIcQuΩݦyܺ߫ "OE9r\rie "y)838/"M<[Q/VLU EdQ\ǦYA!"vĩ4Z"j-R-9(!ZDi]\JDu.Վi).5.D$hwGrSDvN_P "DdVDD>"r@-ۯO5+"n5ɾ\ m s_x lxFΜ]̱k5wus[e,p?sGщ%aY PLJbh992`B8YQ8w oo:~)&B`$c 9ɘjhKFj XiVJB|<“21JƳ&49s[tCoCF\+%$kE$"RT@HG3Ֆɘ#7dQOJ2zaI (!9]5S;~Фhvb `mk_ XI7byDĤXș2BdajH0!f{x %D\;秜s? 1O8E,iUGxo?Ƿt{xSR-4bCI}9Ӻv%BDAYU;!dY"7CT^yR[L}GIO!K/+xVNEm)d-A>q5$Z}z6`^Ǔr_';ؒ} :"B8kXRuZ0I"}Eׁ7H Y`8{4:WHoDpJ'vgC$`>:u-|xgɛz<&GM6d>"([xBܠs.85>!eS&Qo7kb_ӊ <}0o~7a9IO5x<\)^25V*\;|\te<!A|@CzwׁA&"fy +[=ީԆk":.K,Zɦk{;,~73c|8\Bz]0$bIJ<m%2qg*36<J哺wΆLٞzµ|?i_;Si*_/LgjxKsn%"WR&~?U Urb~J~iJi[nQµymp:1uzEbs}KDj95♚1[gkӦ}XIpZՖy v#އCq= M poR^-5Ҕ]w:p9F{oCBDNRu&_v]K뺊o^DQU ^VsTgF&i#R*m4f!"ǨH͐ -ws+Rl.˥s]"rOP3s\OGK5ZG:L/aUO5s:~X$wk"t9Z&,8Z.]A1JJ9>M8nCK*1לpDOG)G8lx&]IҌk 9~bm G>`/]זa]J~O#"rRD⁽RXm9᜻w"4-QjIPS|ÄomVڋohd *4kzZlՉ pD)Pm %V`%ߍPZMDr/^3_Kvr$`2D~ZuVxf ǠA2UDuiv-x(@+TY Zc< /5 Kk?ID mzi}5DJէYS_sO6I]ȦvBF`ZF2ƈ6:BTZ4i9Цkk("D$BXFCp$~:Md}b< sI[8iWYC(t+|^#GF(8~oPp͡z#D$PXhN5pe|}ʌƷ6>!D6vs8DDi΀^s{hևfMs Wgt2ĪI ]mlt5d(~jH9w;TwL"4lDmwp@yɣͩ؜-"ڦ'<tkSO $P7;̛wA BC$^&D$,r qW̥dX. K6y({/mUM8MaĠ_M)jhYRMh k$L?3$MGsh1K`A:ik'$I!CF@[2B5N<7Zyj!iѐݲ$@T~ƊߑQaqHr~*)n *arD Px aRd;ţZh+].y%vEr%FS 'y~Oۆ`D@yu[AYyk[d1 ;2AA-|xή[%(OToHξ3ze^ آPgFT=ᑃ]>#VE^;ZΟ%wFbT+IȯZ["r>/-yU ]f60rGGb;+y ޢԾMѦaPMYe\^5ke;5)ٞ965Ƭ* t7HmTKq&N$]#[Gf(g#{i^!l׈ET89-$H³ۖo{4!QK?ψ,,2O0s;;B= ?<NqX߈`g|,6yv~PB/)jE#9R;kh-!ʻϑ P|g?Qu'Zl'ܮ0CP)h*xSs̨{ m2\<1rLJĔr枖ܳ=a]t̓5Y{IENDB`ukui-biometric-auth/images/Iris/13.png0000644000175000017500000000655614064326115016507 0ustar fengfengPNG  IHDRbb 5IDATxk]Ughi)P0ÀFL5Jh DC$~"A4EI2551:|0(J|B1 B;gs=:͒viI󒖔ӼQ3p|ȬbZ(i(yk$ͭ3,va\-Et`4ȬN F̯YJc uBb2)ڡH[$5OꍩC;+(" 12B\0Ng[d1r6/I̎2!Q񺫵7( v6zk^VP.n(ccHcR/߼q#W\2-;_s9ON{v Qk.FYӖ \NYc7lR"'nUEԫ! mguqZ*w(lVT}4S! S¥]ÏYR66q=*O=[$QxSl >E 5GecH#A)S+C&Q;R~G.hA\+K@S:-7&ԋjM.rraoZ9SRK4Ū,jx%%R6&vVW6xkz]ʓ2ʺJTx@j#R6un7jf+힂Mo뭒WV+;e3R:5îċRe U V~_PzO{Jj `4q*լyV͜JƉ#PV;u@,3ZWRV]*)5`,>O=kTڱcjJڦlnroGL=U6|ZsM{Ֆ ;23a-_eKM%O{.qK(@e0dK/.^ vp0I7>Iepdk5f'j-g봥Pֻ'pwX; 񰯰|mR.5)Jb=w_H~R˸MS5B)_<.y_D.#g4p5GJ{֥| Gue=/sc-0Tch@Q)[ִR//ʣj>]J'(uf5Rr#l RMO7423&2;9 z*lVzv**&V6q5pm2J34f`)iM&%|9[\Wu%0MI",I%}NrC%$|I;%'9%fum7I0:^5dfa fF fB@[M;L@K@҅^' HMtK%]"is[Z;%k˥Z@80v٥' yOؽw<0v-OmV8ז'|}_$ɏ j i';pkl?^n!'A9~ v+s?pݖfg+$R]5ęǃ[^c8FjeH-R+X9 O$R+jPo/=][$GmPSvJ:ɜ}Y02pnWᲢ[#{?0JkG=ӼZ<>OF"02R\{wF<  ?V>F.S ^G6LE>38Tqg2a򱥄["qʚB^`R7G#έb9{q1p$Wɼ"~TS?<͸!qC[[IZEYmqøy5=Oyg>$yČ1 ~ U8+$:~ӗͳ 'nhw(Yax|݃w\unZo\v\g縴H%u..-( Tl)`!d;jzr1p '}BȎ$0Wph *¼֞}x{x-ye6Fwe²}AE|O#ӞwR(/j=(P`^j@*sM*#%e7hiT45f. r8bFJ0)3C$e?λ8 ^CVJTeFd/lFQO㉃^_ۤ+Jk: u (ǔD#%P.ŋ?8v(o d %Ӳ%>7=/b1{iǠlrQkوyY_AAuՌ:'eIENDB`ukui-biometric-auth/images/Iris/11.png0000644000175000017500000000675514064326115016506 0ustar fengfengPNG  IHDRbb IDATxMG;>p;!PB\N!wbA. `8 րC">u%fױ>vuuLLOzRgz^Wk`@DȂ, X,AD&EdVD$C'ƬLB*|2Y@PD9L RJ!"3ELaf"VyKADz,2+y0GӇX%fFY]B in w%"SN0BBLe%)PYz-K"2=hM@C:sc$$av`  #az&CDm`OJ_Whf;n0MI2s]"Dn?є$vs})` cIUBnW7[)՗7\ǝsUn`ve|ގe{VA8:~fꎐM| ^uUݕ-:jsI}5Ҭ[5s2y}E$.HSP/a=ۦDrZJtuDNJh%h$#mb|ŚzlwX:' >-]gUBIz#O#O1#|e}K 17uAY !!a&b@*5Ҵ|%z#UIͪͿy}O۵I.YͰP#Pʴ%Cdܓ$oX޼qW\ǃta!Ǟ!#d>p=iHY;Y2 *ҤV [2%i(m-tTTom`rJ”p)WFf~ Z6Wq[?Ɏ O"s!$)I2c*Ri HhkCzj(Ǩd$g[W*:#9G'.ޥ|b) dțjGÒ.r|a'^c娀fI- +ӓWʢx_ H$'6N\ҝW),lg͐.ڡ2v5$D$kjM]T*:&#*{ tx*yIk`GNґGe! #Y$Qkx X~Y=ڡw%<`5;};I]tL5 vyGeJ IG~B2 '-(i5W;2 ^GE&d}R%NSWuiqpb)uF3Eu/UG(RK(}=ogs_Y6/Б6iľI[C|ƾqnDd؆Lȸ"0YBG;8_%C}hyWnցWGB"Ύ ͤNɓ{XDFMv >VpjevѠ#m7xU#y"8mؗYM=,"{|¿`9go롬n Bb%Ϸyvf1ιN HOen8.4J:%CD{=jWd< iźS]S kA.k5`9jB$E0" EOXx36dzh/.(D$V*:>:MBp;(І秂dXoAC?sZ< ni_ YH%d^t>ιGA%ދȈv|νǣpx-m&y? i*p򽇴 &jg?&!v|; F H^?~]vbd<@BgO K{6DxxRƃs)N6Fcϑo 1 _ARXqE#wE4N["l4/BR< k5ϡ,d,YK}=@TCm?<Mw!A#v~$&e -;;Ⱥ-E'QO YA?i7ᆮFvh?6t\G$LUܪF`l~РcP71'-ۈ{bǭһL𸊺p V kN0]&|r̳v+2]IZs7YAUkfL}j7ٽ9>hV`e)+O+vXе:HϷȳWРyb7_[ ț 5.w~ ov*{ hv6ZHAu*VDW(!;Ё2pjK1Gybe/VK: r}(] N;>Vpv"wqɎ+tAi|aOAetk-)O%yI{%c?hz/i(~n. < Gi vÿ,e z .#+hQ;Qfaw5 Es3~tOp߾tETw$ymB뵕=(kH½~˟:Д:nOg!@KOSCIR=#DHugD}B aׂg*LCQ0Ϛ $mS%cV7"+(a =69ٯjHzMkF@膚CmE1M1!`I6{T(3!7b׆ iY ߟu}dkʲc"?ImY!_ XC[Z@te6 9IENDB`ukui-biometric-auth/images/Iris/06.png0000644000175000017500000000746114064326115016505 0ustar fengfengPNG  IHDRbbIDATxk]U{^S81R\EUS@% JBD@*hAI $h HU8 HE?8%!VCq7n38S1qJ(kmDm'tu[Z$`{q&E;,=і92n6՛P'\qVP wSO± 2F$jd W3 "r]<)ѝx Șe$hpc)hܔ1W;C6'bM9GƂ=,:;yեmJ7+΃dҐQ ǻ ogM>/Ӷ-!/TPs!RQgHfGLb'#vMm۝[t(6IǤ<_EA>>$f5bpQ3Z$"oBxgӶ*< <|8\!\oEDduQ}YӔ㨟 $CNn卿 e@⩁^}j O kVtǁu90Xȁ: 1 mgs')::nfxmmG?Z?%d-Zy9C'P~'+7MH5w 5V69B82K4$Eti߀^ "S4ڑ'))g'e$4%#m "< {$;W'w[K!G/D8P]/g0>Nd#b ?* UQb 4paoVi : \>2U1b7%#mT|>+x7h~%$⤕ysQ_"ŀ)cğEA4ר ($`ae@a+>G.SdEhl;~"&\^~wue6lMD$V0":p5(F[gTq"4%ç%)s 2 $ꂢCh܋%k7),bk0fl2!~Ӯ̴5V14^xKL>7%#5NF3묞{oPhx$d5V')+-c%'vd0j=NP;ہ{i6s(po7QB6:#'d(S\oYABGM?BG;(\VQ@ENWlU}%q#ڨ_^NMߏo46 73 >AA gO"?@Y4x E{bgo)~dF ir, S*ϯ Yѥ j;h|j>ۓJW):2u7?1)kTa8ouG뜠< gf OIͷ#QmD"lϣYTt=}ܙAo;m7Sh݌7*Bm;_j:_ړfvs; Z?fBD*а?~;OP~LDƤ;iYa7:.O]au4cLVQWs&CHmzl4 ӨKOtJ>]A'"'(|vD_ Mq#J>"e+gmqt]z'QhS=f! 1}=MyF ;6KFߩ[♈6 qX^pm`$Dt=&S ,0frԥ~p]qԖ ݹi騈hG;YY90 aL :XFqj Y59O ,N'wvKf UNWN[&unn*jxYwξO֊l=JdD4%# #^53 gs"m&? qmM3q7 *6ZXksDJK]u]O"Rѯ}b2#4mc;R2vlz:p8aV*B8y_Tkݶl')7 gwRWT,]1z̨"sW'X5) @յ.QXx.|{i@Zi"+n&9%%NՕonxOf\}0%:a;GWёzo}?y ^h.o{¨adGeLf%T68\ühJț #`/zU`ThJ) )Eҕ eT$!qninQw|:Os!Vi hz{a7q~ܐy?<BxmUAGć*v{0 j/ Seڅ?eL'>dq}Yq*8MÞZ56~//]Egk }[Eu_s?g 6t;p_]u=(>Bx{_Yu bɶeZc&k@qK!1%E EWVw*zEʗGLFC \}ˁ(e3hs.ZqhYN%VZ(.f6F‡{se,+.ݥ#Ż宽`x=^GDݔls8eܷ QeN67MmA8eoQOgÔ3ѾA-)si4P!'㪋gf$yX!FDy8@dȈ/XFb[eu}Tv۾PC21v 9:淴ԡ”ŘYh_Q? 1+qt[\W-ƐčzeHQab1Wőq1!"c9\kkhy IENDB`ukui-biometric-auth/images/Iris/01.png0000644000175000017500000000603214064326115016471 0ustar fengfengPNG  IHDRbb IDATx]jG$$,$lgO =A'p ='0{{O /+"4E&!1?隚I uOM(30^ z+{w[D{Q⦂a=f>kY#%3mS3.3((]f~܆\ A~˻6otlH]܃iȬU{c9=z5NDDͻWXϹL\UcIsDtU0mK/ot i^sF,{[)# )V&=bc"_Al`\*?k08)]S$f 94kY"?pՃiM 08NAIn^mf{1 0w`bƭ CHRe#9]0)Lsf ݂i_7!Fc2pc(70FL[#uvO?n0r'U$DoaN붭kZ'AaDD! pL0iaMd+[vJ0dzL=vUp4 ȯm=":Sn\|ꍒ) @#A:Ul뫍1L}l{JDt]X݋~d XR|\/j\x&J&B:&vqt~wyE^k̼!-8vA#C[ptb$Uqu!e>C&Dţ63/Y13LV 3/dA<"y @f F7C~gD:fU`[niDt%)oWx -d$\d $0c e0dvQ`/A|\FD/%"K.a,!$^)폸ڪmH2ǎ c!MNfXz2lqGe !IIYFlK." EhZ֠c=&4ʛ+#F?% JBVcNuE]ڌ :kk`Lz%c$G)k^a43&x U30)#DvvT ^U'6s!k[sTGƦ!ؒUTLHT@LdĐ:pXĖcoWt֊BGX>/J iA9Ie~Yjd0haE"5禋z2d*S%y?:E@XN 1SrHj;a9jG[Dn9G}XitoN&Cl3I(x*7y`gW)S5dC]":֙ihiT kB5EHʪGé9`8_NqZt:Pa.1 $ @?5,*Vn/12!8Jݡi餈IUZ*PnlOL԰ G&kN?lw]LznJ5㯤N =B=dv'MЁQevԇ 8qg[w ~N $wr,(gvh@{H3KY}'Ia=ij apēxOy:SQNuG})>si2& 3vGת0>T{*sB`38!Csvc3Mg?h +G3n(e{VVcFme^=KChr-9ZL,k!`[Up%wIENDB`ukui-biometric-auth/images/Iris/12.png0000644000175000017500000000670414064326115016501 0ustar fengfengPNG  IHDRbb IDATxk$W5;dlb|fVA g!*$DA((*fb"H@$QJ5 &$lL~nݺ]]]]3ꮾu^Qp4'iYR{|$%/iI ҁӂQ3t:lV1R-XdfJ7ƙG8"I=,2+.C [A/64.Abh橐X̸$EC٦ݪErmmˍe.i0!-(;MKv,녲0J]TTu(iC`rV93rc#\ D%֎ҁR |Ś:WV۞1Pչy??Ķշː:fnpVvQFH٬p1 {iS_ǍʹGM\("ecAW*s\8{-$J!3ry;j/R:c*X4>Z=Ï=Q2?B)=]ܸ#5 ޥ|b)xțF}M.r ^r@w*WT+)1vBpk򢌲n0nȨijM][e`DvOsʦWV+;e3R: ] T`6Qe2Ti=Cς+<`uJ5+s޽ުSUɂ8@e0V? X=KVGmJJgAf~B0څ˼|uQR)u9` 3L=U6ג*t/Xlɼ΄~'n"MoU4/(\PB{˫~(\~{~3I[3tG:io"#C|}=,ifv\<[->4snn& w4^`*t\*kRv$JUc;Իi2nਗ਼f/s ,W{,HY! ܧ ԶHȺԀBe~e)cj@{ѲOJOKvO [ӪKY:JϾJMҋy.]+gH:[NISDěgF~脤:<%i c%] KtIzgKP>I)h+q*!ˉݣ}0,88mwwV픥ǁoX[m+{*i"Er1^Ҡ_@haP*a m_o'8a}L}Q! 1lX%a]Tn d-p!vv{w! |7p?bj,ٵ]$Mƍ#}eYFy1I߷Lobok׷E _ |:/= |}>߿x:$ɺܮpp8Iz1Z pفQtr13+7YR{,=K?X ?{kkֿڽ+@@nNk~zve1xy 6o_q ?a * pͳ,T IƯ'qŸ"k/>iZF70&po0:&k~|\|xw;QQ`-Iblpj*)! ~_s70&HAHL8ʀ^X&K//De֒$Y!J1ƒ0 qB}3N {7r<+)FUz׭p.\ Y| i"r(5yzه>i҃{i+i N6v)BnށK,%? [s:]TM sUL!]vWXL$}^P`b78@}k? od\Kp7&KQe<'2@H8.WTeopXlmKwc(!z{x n0 |-|x.7>皻qEu5.>ˤ~ne_z\f0 :"v .}2meWmLl{vں񶛬K;sAm:5kE\&zVC ¼0ۃnz +I<5`}=p`ח]viv-v /8`vgO'IS89QBJ]KhV'@ЈߩV3[ePORnR3}FOScFR3Di3"0ܘP𙊅2 )rޥXgC${ Y)kS}cp{+ƍ _0;~8:_8M>iPkrLyS9rhkgr)^bƱDS 6n,OT4IO,[ r^1(\Jlļ_[vxhH|KIENDB`ukui-biometric-auth/images/Iris/14.png0000644000175000017500000000663214064326115016503 0ustar fengfengPNG  IHDRbb aIDATx[_G?gw{IIx)niU Ap+7"J}pSV|}Gl|QBZ*VEAof7ׇ33gn&\3s~3m~3{.%D3@V$42}aI{HҢB:0E~bIZ?c'QOXJkXO4M:%I;EF6V"I::S:dpCl'zDپJҎcY@|6O)3鑴 $-OqRz OB.8-(#L"Ej`X3$$_<܋g,iFdf7YRQEfj<єX^p@]ge]ڔ!|gA*ҬB'CY}-M}w^oSNY=>QF=$5˲ilue+Q.BkC'l[˓6/ m[f(k;H=an5J]7(ID54c ,н&˪错,䂎@X{O;f(KJA% ꚊWn5ϮR{#%G5h+ekɇJސejzdLZ bb* &:֓$T AZV#'տnE v8 pCܑMm%Jyu7sEl G [K]]!FڧRxuZ9Z$TM [Bs_ gmbTK0Gbul1]Ry-Kϫ4y@f*Z ) *NEk FKuocͨ4hә1QkQ&fٯ?t^݆ZXI 5y[D=?T1FBMvR,f+^uVUUO4+U%z-*zպ)З*ԊVl[+GkpsX%D7v` `*[տd%-H%i$]n+Fe.ּ7HJo4N(&1ɳI?(זukX4I>ϝ3 { 8!O̲?Jl6hLc ,3o`(tBqʽx3`@Hs.[+,˶~V{}>VV@Xb]#Ymw=|ז9 !탑:9P{Tr |y9[]> sY}p(@8qSf=-`ҝOWWJ+ \|xm{;˲V4;@OmiA̠?O-ɵ)q?w?~Gˁ}2[Y5P I .@pW9g`a`~"#Ge (瀫1Z~*ޟ{۲[쎭,V:k];<xȖq`EUĹ>X-rl-`!O9#r.)]|\c4 fTEVP ()[˜տIwE[2c,nu$I?|0nrkw|Y^(k AkoxWwMߓv Àpq),N[ve8P7cWG&zHU0|*ap=. %4 ܗeSc #|>E?)P|Uvf!aLb$v`0)0q b{xY{cX}b06O_eIrT廯}L6 Gi.c(61퉝cfbS? /iL\ ݿc<6,̭Mo1t!>hּ+0$)u >kI~ ًe?ߦ*@¤h fjwtă]X=I 5Wzl>O:9mgc6ǿ8;2esyL 1n t>&wr M o=Qw;>HԤ0]'fIDGC o„M~>Hх!bM(.D_ I p.z"f.4q߄ѝ+W&_1ǯ03л0yxΐ:SV֖DlR[CfͱIKq&,?O=QVOla}Aj wN;q 3߫{v=;{?,s0:LvV'~v"%Η1s}x,QoǙ{ʞ];euc~]}tRǯ{%]ф/a2Ě~kFѺu?nip;eɌdrL ?λ>V/Տv@*nxϦ*b@q(҂RvI QSnD*~VwI6 0 fXwlx+՚,`+vk3;dߜ?V*q 0d&mE<\ĉ<8{*Qnvv)-9k ~ %c15s/CvMS/8=mJi9k4']_녨'CB^A5 1PFȊpL&2:\/_/!h mׅ["˘)t8fjo ;+3ʴ7碦œW ÂDUDOJ]UU_yQJ=+^gQB xVJ}RJ}DoE:-OfUk71I@&ƎMI>GwIb DyhWu7L]LؑV+otuo)PgHB2TP˕CO{/L=/t?7Y(tFH"7& {r,M|.@Z/t{,UXMIW!2I]]^zzؔV z՜j@څ5Cjc1` v*[])w7_gVgB촧m+cr\.{Hqzb ʑM◦3f388]^Qolw Iq-n8f̀wukbWq,;>roQ"I>dO;~Ox:b H1ޙs0kHDޡ(2q9jJiGxdE;&!Bn۹: =xA)%`l'#VH>IĆR8y6˖ sc6&]<%<*|UVuY*R~CVLf_y2?`iU8a{\:sؓhA S&\6 xFg &ߍyH> ]ό\&H\ɔ;s ad& I(Wk" rA&3ν1O贑vJ-ԮD"jl vZ`Ƶyݙvm;\r. g|EtLI%?;*U[Be.oRzy'~RJ}WJgUU0mAG)!!~-_'œTk:01AMF{!u.PI !4@Sh(1 .ncr0w,cu[HŒɃ /8LLf=)A6iwSi ŖI ah)罒]c;.IK ffD3r33&9e 26ޙX I(MxAI|ojtR*)v/&;}6Rya^ 3It%~Ls??q}7f vYo]j~MvqX⎿Qggѹˌ V"6Qordž}\njg.&M -d Ro61LwV?HILn67AIA-V?Ј,(flT , r̵!"Ol/jz;DLj$@?[֙2DL+D:#St>^+{p@4u 3Dέ)[WoP룩]UCSb0Qo0;3]{H7=HhMK.i+7NRh5'̴n&)F+)}k}?㢻|ںG7КV&v mΥն[фWᄾ-sPv*j7AJsI@{%YnjcUU.H/o^Uo_Y0t1+2Im26 a ґ$y LhYXt6|y;1&0 2̻&Dc,iބz.ճo v1/, ;\BJq iɝ]nr! 0Pi-C@/b`K i]<3l!6-2.x6,~Ҩyu pP{Xd۹r|ʴ\jnwWTSKtc Ndd #$IYuL{!r8+ rߢ/U3H֤FH!y8N|$ɗz %)!)8cRAnPg/ ȨnjM--sFutq$FH&y% ?IYgH>&u<"uN*=Ac$PvOLo3WҾͣ/-Ƙws q9E:r}Eq/< R+;pާi][j`3L ݈Бy^!<> ۰ԧ55Ψo!,;(jR_pXZ$wl1Ϫ*YD0mDBCNKDHB7dЕNKD9NFѮpۅdIa ?Nm<JHНuG}n4Ϩfs א4n`;\N$Mi&]U`vAUkrxvx4?,(lЬ5X8"a$qUGz%##s&8"c^u[ P kDCB!I2dvR",#hΎKKjj2sM\j Y},ɤUƎ65"=#>C:fk7g# D%Ϯ-51 a{x0A &K-*9_ppc ;cx5 i leP[D`.;tuNgbgO¯Uv4#5.;ߏiЈfCO :]lo4^Odms]GK'oS:*g;R;GIr6S [Vjv}siy#=#Ϋ:D c̽LZ3ʚa(l>L}!1cU&9Y@kF!1f  Fz I  %mXm,eMw" λH*@I'r-Da ?@M:>S:T2D\#&[N(je}"HLa2r=2So!$]m 6#'I+cÎ{sfY*hy 8Ltvvz RsSU;EbK!"ҐJ%}G7`pSe#a)9|/O\^mca"}X?4T9 buߐ cۖ{1KX)<?r 6d tSkG*b@캫h'aJG=ӪeǽdqKY XoB&a 2`gk+R1;S@,.kƘ_]#d 1ϕ%e@ĈƏ>O=CJ[/N ו+(ݥ廧a|ch؄}­sKd,|ʣ֣d65)0躅X,k1aov҆UX!W>gq a~yŬ=  K _w_|пJ(VXŻX 9|_/ij.Uc !4\F p ZgHii3Sg8o>ks3dg_ξ|kZ{."r@DEdnr̨wȖA7.9$"sǾ㐈<-}Q*"ExkETaFʛEo}k@j%wȿvbQZk!3k]5'tGu ZRD`mq""E*KeNDnLUi!AyA bI840AU %aLB3uqg?Kb(3} o 7MIHDȘq "ua mkFEĭMʦR sBVw˨Qڙ8g?sιsU}aݽ9TuID=<7&#p^F )CpPJB 9l}9O#M6ׇdU%h Xm%x'%b9N1 \{8QPɡ֖."}f]J5+O`AU$cI$t EOSιǪꬒ9K""2WdXQMJL2z`s;_3S,N@ o};[RdUR"4恩:&p#/){E`QMõ'g?/KYV0r}L*"nDžߔSD=o[x?1^.s$ݾO E@=L Ee!ι8DĤ.>F <ChOkF qr|]ddiY۹%d[ƻ.PR.܋1[qʶa= ]_~hmfUEDX2>x/<c͏{es|9Xz)JbE0NVفĄ\|oGgq#l%"86s!-1+ǝs-/bm%V|)G-7-EBFNT:`-||1>}v+yO0NE"e]T1 a|/;Y#)s@BY[FFN\Hfq`C|F5O:e+RFrYKA!ڠƂh?|oZW>xL) EmO*Κl㭈_L:xI5`g EL2y2,BDv=7Zo)5vip*H8>8||_"+sQN0~(w)ue:aLU`ɀuCe6?wDz2nަ=y,aZN=6oG&#yW0o@b֛]6.퓋t{ߤnכŖH,7]m!4p7>ϲvFS}SXѥОSvލAgqb;]`w/k]TIE-=6 |U'w{x0]q,+Dh,(j uzx*O[?󊞓*OKt܅=fo+/ƺ+*dV]Z ǖ,eAw3| 8^p(|*=="SvıA#iƮǻszj UUYjݖ.2mi/8ި8^kwΝ);7ٓtmUr%<˖r2٪vCN:q?5(9il~oѰ}~#D֘&Gm ιDd_>:O@q]Nshj""#Xz~ .`5uadͤI 7$Z쪗6.yܙΒU:]%QNHԞ[Bm/$5H% kŢ{>%,C]i04zLFȿt s05,0drKg%聄Y+GC8j5%jwjZ/"AU-a/j N?50iDky?]8ywF v,ݹuj3{knFZ ICdwz;e8phѐJIJM3u۫N^3'jvl%֠ :*[t )dنbr m)B%ԵPVjL &SGS4Fɰė>3E̝Ap(JruGTgǂkvF%G89mlJ|0sl[Zr Ȩ|'6Sf֯ܝ{,% <T-* q/ Z]GТLƾTk\!9hY~UY@>No;{W˨r]M>3j`.=,t0> RYx]O4E>h4L?9&"Y"7_=. t5%èl'=*^|ZjSdo~O',^-|.~PDTM;O(xcǷl^Rc'=Y[+?/(;R-SUQUvr#E %!v72U7y{4[z/~沮[] ZOcAWnHf,LqbAFd $n%ѥLxc{ZL] ,nb*"'!(;hgzm){d_ge Vt+&Lrb]i@j|bc큞-OD)ӄvQ%oö+lw Ǒ%F(C3}m0G8u&'_שۻ[l"e x:~ f2.M!ɴ>^oo1 nt$:=wHmT:AO;7$UyQ/!!aF5bt|ij o. dbF1DG7Pa(Pg g! 'L:Fd2#X5xW jFs֤u( D9YY~~f Q+ppMTMΉ!r~E+b`)䓋[%@ L X}@|m^\@SEeoIENDB`ukui-biometric-auth/images/Iris/02.png0000644000175000017500000000771714064326115016505 0ustar fengfengPNG  IHDRbbIDATx_W?gwۤ &&v5ؚ*S[|ZiDVmQPhkZ H5VIK[!1&$6$fMws7?͹3s̝w 93.cE:ep.|AG!"w˼Ki bh C!BDƀ =|<~x8/\8榐~ K5?_fP2LJD _ި/ 2)hJF*", 1:{o=| yRݲ  `#p/!}]d$MN1q>ʈC=K1RҩYt=hUxX xLMc<)cu*q\Nt>ܬ|S0 !06`/k xcyͽ%%SJE$/#Ἱ5m}: i sjI$^=/<Ed&d n)hF>w>nL"{Q%aR `[`|L BKD-Viu]2,RHv7<~| ~<XLDD$KB x ݪ2I)%$s\u=xUuҗ$" 6{+)*$MDŪ~TK.i${Xp+\=!{Y({UfCa {_W9E")EF=& wRz*yz%/&E nŒ*/ ~dKDV BMd 3EoZc7J ̨=L-c~$~{Em!SWLKD<<=sEA*lFQƅ(\;8s|%`*"=ιDd-`ט3z\P㖀y|7eNj"6 {*|%"?sΖX YWOXSF_szm:"O ps岰Dȍx< LW}dPhـ/>ɤ`0ث~X22#"B;>V'[79BI6Y[q9q|<9k'sl ԀҲ,$BkSs0 4/PSs)^3dn-m4婲g#qνBB&-YհFhŤTmHC@9'%|k7IvE`F$^t`cP >Sz><[u0rPsjvCDd1PeԂ-uc\F5ua1 b҆wM+b~Swզ+K9w63du&E(ؤ5MںDCcMj'"Z%ZK@jWWۘ-n&`6Z&#uZL| BeN#šakw[\DqCVu=~*3dD5.iPT̥N`% g8v'5`j*: &ζ!Li$6ti!#.!SFLφWF#V9׷rTɈTj;cּWN(0&^ucGԖC„뾓 2نbr&VPWB:u'ɴtEt%zS[y<~O݂HNju$8;P:\l|N[MwIH"m F3;)`DM6WɨTUzt ~kŃ4s~uI Q4Ma%pnn7QYѼ5FgP;vPqMA$2|v;[EPqq\גW U?H{gE ]2Z]t}'m0В6K| ]l HmVj:x`7^^ L`FD;jiŐU|K}*(0^/~fPDW,ZV(i+M"s a<2f٭u "vޥJ^a栝!7y+UA;N$ ^)"j;i-lo2|wSx[0cgso/ SYTƀ K&70MaZ!@ ,n`pUD$o X#QU;m݆מ),kA>٦!Vt+}6Lrc ,Sagy5~ ~esf했|x kp`U0_he;#aa?~];K{z`4 xRR_֓Lh6]l|9~G β6$[ 瀰l(ESf*ӺJGDǾV?|ADr::iI$4C"#A#Z/"G4ۆECCpe22h ̲`"߭ʯJ( A]/$$’fMHHzCƾ&f!"{M\^Lk= rdo %g7")8#V&D6ǤنU+ "r!_WE{ԜR:h)(C(_mwjՊ#DVJֲ&gڐHri@E bd.䝋[F@ qZv_ҵ?l2.25kɬIENDB`ukui-biometric-auth/images/Iris/16.png0000644000175000017500000000640214064326115016500 0ustar fengfengPNG  IHDRbb IDATx]KGzqBKH$a D;  !cH@K@h VQ  0F ^ds^&3XԩSU}sRw:uGtHDr|L dž7"BrDrFNȏO#+C3w_:%V1<&|L[Drh(̦gE7HttHd#!҉ѭQm!H8#HkRb2Hmk,Ӗɵy'; S[JCn9+(# ևdD0sU! ng,;Dd1h2A*!]uwwo8a>@vm-_VXV3A H}76u r@j7I|m %˞!dob6YrV7ht*t}jKQ}[Ǻ'Ƕ#SKIن0W^KnK)Q_*SY_پު(lQbByfMe>$[/%be7{̏dE(*fWﺪw ,r8}g!3uKh2Ry"7t:zj/R(vih* ><#pc#0`jݍ(zɖrt”}]tb:g_~;i:3[L [/#6nz, X$tT>em:yfՊhѫSs]R5ĥ%;B2m:30y7q x7cIZX ل jhg7}Ql6̈́XaEf溪#uߊ:,0I#%]hGmߟ>ۘ`T6J*Z~֙wե 9,*8PոFl'+]]]5fqL}I9 FyZb« sK d j]BWJ;bj7gfW$'&kn,c_hd񵲠b쌋V&L:ݷ0fGHiVXp'_j,T"J5]$&-ja+CVݠ1S_boZXjݹ_u櫗̃Sksd?̿VSWߪ A]|0_0qc>=R&)[Z,yJ'Y,MH>N$O!oQ J@ٲsJ 4b>eみp Aiߏ* 4>1 k]v,{Eo5s?'pР24(Ky,~8Pf hAj^}Y1^NDG&+*2wͼeupE9| /> `Km5+G1|G~?"!0U,vX B(C*!<0eom?(5F <cae@BSBL I,/ܳ ,vdjpx=x+L3YJ(~ԁᰊz|𷑃#v@hЖ:_q[s!Kŏ!~U.@} auW)%8~L_㲞^PP@1OYC i_V` iYw¿֖Q@ )kAEV)!0Uໟ|a0s(xڷ"B)|n=.UAeA?P'h7*!~wx2"=]#JDIZ[IJnaoiد`^QO(1-EO@Mk~ȏ۲+=f?5 PBϊfJckY_d[:ꑶ8=Oa<`0?s}nI=W3@JgC."7x?a䥄zR)e^YpwߕLyfM hM :ˉϗUo$Tiv*o-f7!҂1SHIENDB`ukui-biometric-auth/images/VoicePrint/0000755000175000017500000000000014064326115016716 5ustar fengfengukui-biometric-auth/images/VoicePrint/08.png0000644000175000017500000000236414064326115017660 0ustar fengfengPNG  IHDRbbIDATxU0x p'vA N N9ŊIllž{y >]t$+D&,ʜF yD9r0gpas?<Pn[+=}Bvg_G۸Ѷ}~S^7۱`*e@DܷccĕIߎkfM`mpܤ~@څCeSBI.hmMB L}{h# MEH npɄc^xNR!"LLP`Юg=B9z8Thf*"f &D&`Bd B "pфL 6]'5֩GfJ>t ,1N$i5SAFmG j뽶|FUBWf.o! az?]йg/ ojb_-v0ZgG UòEΌB Uﶽ[2_?wF8rg7ɑ ~mijru=}ީj,^`[q,-RT pھ)IENDB`ukui-biometric-auth/images/VoicePrint/10.png0000644000175000017500000000237714064326115017655 0ustar fengfengPNG  IHDRbbIDATxY0x6 H' h' t Nt X/NV=O9]􏤳$D&<ȣ-K)ɕ56˼Fyr-\8 R^y/W=:Dǹƍ wڸiߎ S)g""f#v$4cpv&U:~MBt oU$DOvtgo!F5Si`5LD0!H"LDbEDZ9r+:lOklSHpc<b?xM|_):%L 甊Y Z)=ZF^~5|eU먷-8{vTSe[| HκPo+7釂S""fҶ?fDjD#`GF" 2JNGb7:X]P!5h7MRch/7-D&2=m}b"x#DTjZ$2Ϛ4kD=߫Y1W [[`B$ BVp dڨIo:؛^wi _ݎ+fZw憢פ0T0d n2$2uhl#d Mo;C]gjýS4$]ъR7*~ƸXBȲMNFڿ}[Dx'ۄIDmM5„ć>B&O(_ `Ko$ lH7XtUL҃ Hij}6m](݇C$8YQ{fre }9سi1!(ND)(vf3 rҦ8CM+zߖ$ &D"`B$ &D"`B$F'>~Q1=Ù3t}DŘmWOM#Q阸7˳|õre=)jWE~ ^(6J{ 8BU݀IENDB`ukui-biometric-auth/images/VoicePrint/07.png0000644000175000017500000000240514064326115017653 0ustar fengfengPNG  IHDRbbIDATxu8g{ \ l٫l* `+Hx+H~ hda}(Y=kʊF Uvrz`rࢅ2dvB-Ɩދwnz iۍKE]u "Əq}i^]`*m@Dwƈk+bB F7\npݤ4~DCeM7]dqF(`zG{N34 9Ć-&zǻ3İ0!M!)ݡ ؟ѽ i{hhԜ@1kGО{e?F(F GeC#HU!PLf~v2Ssh 1U٣-)3e?F=Si`ͱk"`B$ &D"-ĚYr;:lOklSHp/-߻|U^wb{ڶhս3Ѹb( |뿷gڶGӺG51D O{.D2K#$m88ՐU;/xWB;:༼&Xq͔5'!O蚈-]f Q%3T!Rb{`<ኙ﬈#2)":[7R! YkM㽑IvIsyVGyϘCSYzZ5!A\lCVB>n#h{| Љ1|akԇ&B3l@"`B$Q!jFNt?jGM25ެ{Gͱ;1`_.LS! bVh2E&]g.Yl7eԅ[%OTWk Fe#B;% jyҲ}(49^mCB̤$c=„ħ! W5|IvMz"d] T%kg4jo]Z {*456±#J{DB-Iqњֽ{LD%!'+يĞmP&)Gȅ1Aq7!wuLvFy:am1 1 c+pw豟&LD0!H"LD0!H"vB>Y93)Tnqmhi OY Fp䃿{Q`reV=]SjԶT7G[(nJgtJǤIENDB`ukui-biometric-auth/images/VoicePrint/15.png0000644000175000017500000000237714064326115017662 0ustar fengfengPNG  IHDRbbIDATxY8gx;t:ી `+`pU U@W{"LDP`Юg=Bdn9z4Whf* ?& &D"`B$ B<UhC&܊.[4"R3pǫoC 5=mu*5㺲)Ğ -jbDt'oX2_U먛}Aj:[2|w8w_B;SGM>%s93 eWlRٌnMQ'30"M@ !~mg3JBD>".B^G+*{)A3*:Uc{Ae_94>0meT4o7ک\lPjBȯ̭fͦ)^,́᫅=P_M~D0!HN!0lj7OvuݟQ 1 U _ݎ@3lHa`beHvCs! 74tՆg(ӧi$ы _4nEyjm+'jI]^8~y϶jt49ġIL$j&D$>2l``{Klu.㣨 ? UODMSi#j\M1?c8D EG*||-Af tBe5}GHu +}7 #8 yFi î=qpoiH"LD0!H"LD0!a'mOpfdnN\I`ۻǕh`{F{z᯽^Up\H5:B}Ke"EP oARIENDB`ukui-biometric-auth/images/VoicePrint/17.png0000644000175000017500000000237314064326115017660 0ustar fengfengPNG  IHDRbbIDATxUH8 Lh"`'f#`6l0L`#Ar[ȺV[E*ᄄ"0p`-hX'7f .z'mQ5>\p9o-.%o^~/:Dǥ_M e{u| 3ЁM'CbB'4*}7iOc9V*|;A63?YBx" np !Nf%;A:1ꈊb莦s!ݱ ѽ i{lhԜvd9Ze?F؎OMvN;BƊG$ B`;k%L\ѣ-D&鳲G[ Ise?F5Si`ݱk"`B$ &D"-=e?F21VttTZ;z~w*̥B\b{ڶwSTJF6xfyK~Ta[/[kbDt+/{,D2Oyzx*5}Bj[[mf㋆:ǕjS1.IH$!3Ҷ?8vu!D`kb{CD_q!v4.?8(%B8c";*b|- ̮h+uYЮ;=%3f~ E݇/#D3?!mkWMwٹ[yh.6&MS ?ZЬr'pc'FպPレݰ`B$ BVkyrCcIwo{*|wҴu_ݎgӁ"gؐØ*Ħ͐LG {pC3Xh'e4UM%ZOEϕ4Bd{Y"B;%* j3e{_DxO Ijt$J mLQ1/Rjd3ck3IMѥ|g몦gF8vJM1!A&i`tȎ Cc1gԺuh#>HwgQVZ(usE1BrҶ8C2=vapoiH"LD0!H"LD0!¶'ΆfdnNh;fnۻ> G63y֪W^~/,{\+We5J~/[~ދۍo??"%Q>F%IENDB`ukui-biometric-auth/images/VoicePrint/03.png0000644000175000017500000000234714064326115017654 0ustar fengfengPNG  IHDRbbIDATxq8w=nwt w`]59l++6 &D& `ЮͩSv5NféDFLyۭ7F1"F'd^`vM;!ڀv?Sz"kf-:ƦP'fum! "DepܽFJBxDtjMMS ?kZЬ>H}nkԻ&B7l@&`BdB۪z%/@xh5P}Es'M[̟ܐz>OB }*c QCqh ֮6C>MMBҵ< ^ktb 3'~ir"l瓆CB,$ aB$!DT^xȆtBLvu6H9o_&;Ӵ!Oӟo4p {B0/$b 25D51B.h =IR.BƯM%1m3pw豟W&LL0!2"LL0!2"B>vò!8 Igw|h_M0x>s~`DGnPwz,ˁkp*J޲({>dCxFkΖ`*PIENDB`ukui-biometric-auth/images/VoicePrint/04.png0000644000175000017500000000235714064326115017656 0ustar fengfengPNG  IHDRbbIDATxY0x6 N:t@'H:t S/NV=O9t$+D&n,іdie^#2x٣ܦecwއ W.z:Bvg_G۸Ѷ}aU^wַcc 3sߎWG};btB'paqRUq ?ʪ !_:pE{'ȴF; Q20Վ-gLDw bثV3TϨÚ!Lh q&<;T|!^x>#!m /g0u=)Lv`=k hKE9ǧF; {eC#HU!55D\9G[Lg|m!%͕1ꀭJhu_H"LD0!Hm!DDn1ꐉ!æK: 7` ŝwm<VjF,B;n?kbDt+/P}eU ۉ}A77{S<΄NϞnUw3k}WU"0]R8 (5B8a1bD.mfº5h7MGv-/ 3WwBT=3SZ7eK" *BЦ﭅PkVYԀfȽ筛jw_MvD0!HF!mj7vu&5v^wi꾺@3,IahbȴbdH|ס5Fxv`jã]S4e.8s) {k*e/Oo:wۚ&'³|MLR ґh&D$>?b>o|jn!4W=߫u&irAZX=ٮij}5mcFgC&F~NJZ$ņ 19;C R ҃'"dMr* Җ^>aÐ(m3tX"\rD0!H"LD0!H"LDX a[/#Zf}83r2IG÷>`8(vtLܛYFp?{Z>ýref=W +Ԣاa/R7JY,kIENDB`ukui-biometric-auth/images/VoicePrint/13.png0000644000175000017500000000235114064326115017650 0ustar fengfengPNG  IHDRbbIDATxU0x N:A B'N@: S,LXX'+9tɒy8p/?mH0'W&  yNczՍ]yo8pg,nthA~m bܴo#3sߎW{};b$4v&>$~UB.pe{'l:>$DoouYTDM1﵎gk*gԉaa%*B=BL%<m,CvD$Qf'VT#6ϱAk9~Q.hh紳!vl|D&*R!"X*h Qq\Σ-đKr&`k!cL0!2"LL0!2A[""MĐ[aӥ}R_^ckzDZxhkyC'R=P':ښ {ˀW{d&fKDErwWf)/O!ID7tnKl rǽVyL퓆:k_*t"4!C""f>Uᷕ-b )gQIZpzH/h/0;J6{Jr}HD yL* 7wNkR3z ]ؾTM5!{VYXڂfh*oFu[[}5a2" \mu84dr2^Q=Qv aoM'hna!|a٢gFN!U[z\//lodu7MF(ǧ&; {ec#HU!P1P"tţ-GI |&`k!cD0!H"LD0!A[G""MĐ[aӥCR]^ckDjxi8ok%?rr|OWjF({*Y(D51"Zϱv_x*ľs ~f쀷N7m)vy3Ջ|ԙĎ`\0wQ'3!OT֐r|R F3f/b~EQHŢJ!ڀvSə{`7$$E|t V#Sy5XFM鞺~,4؈}nkԻ&B7l@"`B$BUv ^ z*|wҴu_ݎOӉ"ɻ}7*DfH&I|CSd! 74|<# MՆg)ӧi$8\BvAמ7W+,{9Eg3$fFD~ir"SBd&[F[0!"[ g_HzBg ?,0 i.Xg=*'Bmκݴ!w!:Js Hg^4t$30#oG h*5)-FcAڨ!".*ihrI8" 307Jf 豟W&LD0!H"LD0!H"B>ʡlg&N&i~E8mW;Gwhr?gmW U t]S)ԾovOgoXO=?ʱU`TIENDB`ukui-biometric-auth/images/VoicePrint/06.png0000644000175000017500000000236714064326115017661 0ustar fengfengPNG  IHDRbbIDATxY8gx;t t*`\*[lU@V%qhday(/H?Ҍ%Y!0p `-hX'Wf 0X-O'}؃ hp%uq3pY'Ci[^7`S\yMWgC(%tc/hpnqJ &B{ZFw ubX7!M!=S(c?{Шj.Rv#6тRҿ1n|js:*+6&D" `n|z$(RB9 ؚ4kX&D"`B$ &D"h HDV9 r+:ltHklӀHp/ ݠA sm[?h=(QMyKpW*m>Ѣ&fAD yy+BNB>L :I^]FuDyWf?p^6+9s"D`+ Y^ݜt|Rl/[E!\u>t!Ok a!k]ӳW/ɺ,iA?2O"t+_#Sy5XBM O ?Z ynil_-lzj"t$ &D" ~[Uv(t?&]U^9wҴnǀGf@ ]t"o3$$ZrGx>t&gZó]5e8\BvA='o V߶œ3$fFDPDXCBd&F[0!"GȄ!PH:pC{ܑ,0 iYg=AT8뺦WF8Z[JD߇(\wP(2 =!' yЕuGH4QCE](M;M%5 hm3pww_d[N&D"`B$ &D"`B$ [!l u~FlLLv綽[|\o?loh1sogf(-=@kp*ڗ=bQot)v 7[~=IENDB`ukui-biometric-auth/images/VoicePrint/01.png0000644000175000017500000000234214064326115017645 0ustar fengfengPNG  IHDRbbIDATxu0=l$Nv N@: H'N2A L@8`D' ~D}:G:Ye"}ʔ: irrz ฆ"/2xD&އ W.n+a_;۸ζM`.{;kڱLiǺ+1rj !paqBEi ?ʺ !'d|lc`3C\`BSvXͨNP!GCIW=BK)c[3v Q& &D"`B$ B̈\+c!CnEM6Iqyujn+w\NX+x= %8 %o#zMHDM|Wf-oK Q@tnk4cJ}:=$ߕ:` ͘9> B^#v̿hDDKl)yF=f~Q#FdFh^`vI!ZvtッS\(ih7Mw]&o`{ olCME~,@iʼj w_MjD0!HBVnN6J{MkaoXιP0cehng) h3UX2$~֡7Fw`jý]S4 %]aV4$BkD,g?mGy&'z>q'PdkC8T#LH2ߣ|Q1á)+X%U {TA϶߻WF8jDa]&Ìt3/}Kf~##7"l*w1B b.BBFy'4n!(=4g.wG="\rD0!H"LD0!H"LDX a[/ p %]fܶw+>f]1}O#8ßz=.0q\iC߫q Z{"n})6 a5?)IENDB`ukui-biometric-auth/images/VoicePrint/12.png0000644000175000017500000000236314064326115017652 0ustar fengfengPNG  IHDRbbIDATxU0;l6N@;A B'N:tN:<Ŋq'ѓ~pJѵdIq<\X_S4P[ԓ+]E^#d|@͊bދ S}\vcqY8]aS^7`CX WG]XƞP56ÅǍ cW 1W6y1 /;Cf6ˈۗO:sXL "v쵎Wk j'̰n!*FM#=C(ݾ ؞ѽ74꿘̍21|f9jОr>F Ge}#HU#Ofq"iχGۈ+|>,.(7†hwM㭑BPQO+OAWHm)􎙿^;U]h_V3BNϺ4{|\߉1|akԇfB3l@"`F$BhwjF6?Tdjޤ{M1U(u%)L1F,dsC 4TvpS3P]kx2}K5(/YlߴЙmbZbZڻ&gF>qeDR ґkfD$Yw\|W{_+Ph֠i (]556±"jwQL$i}"jO$t[F0 يA  .FH3Hw,%) m'2V07JV 6c? m;M"`F$fD"`F$fD"l[ǯ#ʧj']fL$]Q\gw}ݛ5^?g7/xmw:Pm%z݊2"E~c6

c@F\I+sh ISZ\9 ؚ4{X5LD0!H"LDbCD^9 r+:ltHklӀHp/ 0-Wbkuf op =~R^~u$}Cxkdb2~ PPybKf9կ s*%=#/Dվ Q%3uk"ʱT̳oѡ(5Bb"wVĈy- n uYnڳ*zQfΥbH3gTk Sqg.%QP!(Ll]:47íf{ǽ)jw_MnD0!HV!ogs ^ /{J|vҴu_ݎfD3lIahbtbfH&RBO!Cnh<# MՆ')ӧi$QWcjWJCNG^)LkIn 3ś#>*V5MN|P'D&H"bL_Q1tUv=$I)PCǧ*Xg&W|g_'6V5M轢p|?#I+ސ*B0/W$b@c1g9`?bés&96A0 cC~ma_apoiH"LD0!H"LD0!a/m/0| $^aݶw+}7=4A3c?޿aGkV=+T}YA[q_&[8l,܇G ɻ@pIENDB`ukui-biometric-auth/images/VoicePrint/18.png0000644000175000017500000000235314064326115017657 0ustar fengfengPNG  IHDRbbIDATxU0x I'N Nt !Xqc:YO O-, kW% ଁ"o2xiQn#+[o0}{ 8&~7v+ok];64_vl?cC#!{BUl| m8nTߤ?g_ٖ]!S^o>LJ(ajGsZ >BzjF} ubX3U!QM!<}(};{v(b3IebȮs@{V/U v2G$ B 45LL9G[k|m!.$͔1J`B$ &D"`B$wDD1!æK:u 7Ni-pn{)MؚiL9_nz'3qOO_l7=JB_}"FI:Ѣr!,d@iz^FJ^$rqNh*c_m(cZ-DFD頿W7tEDAsT|^Q ՚&Z ?kY#2u#|᫉P[<&D"pP4۪2]Ce$CM4Wc3:PDs +R3uX2$>uh2D&ʎ3PY`7eT5MSIWnlľ#BFɠַ̬Dog;XX49ġLIGP0!"_!ns|Iw/`:kg !EjG|4վ6±S#nwP HJi_qLHj3Z3INz\` %8ۙmw0Jao3tؖ{~"\rD0!H"LD0!H"LD a[/ʇe]83pN(_e`ۻǕ>f+GYFp_`Y"ˎW )2lv+n`MGaضB-IENDB`ukui-biometric-auth/images/VoicePrint/09.png0000644000175000017500000000233514064326115017657 0ustar fengfengPNG  IHDRbbIDATxU086 N@7N@;AA $0fo*N]YsN\)dIVLX)K)-dz `Zfp`?Eؽ5yOmo׎-=u4 FN]`ƾ5@Dd1}lX]%ƞQVaM }wn'!9Tvo*ii o+$D/vh!C3܆h7ބ`cvkhW!V S  ?͑b }*<#W>m 3X؞X&J3/>qo5勏q d<<΄Y1Q۷oc<۞1osqHc̯.hÏ#amؾqF0!H9 "r!$B`MOң pv/W 5e gjvK R1?[|P!"BP樄m{:],4aWiXAFaijWx THP!"V۪z@*[PkB6Y~^Rx滣jw XcWȢy M Bl  h_M+T# 3*Ci*`{E %5gp?L"nQ{mr$ֶ. R )2o{`i"A"THP!"A"THP!"a'ng&}f$n(c}uнYԾޞ}xOEYzԶܗ#ۭ-/R !֌*v,IENDB`ukui-biometric-auth/images/VoicePrint/05.png0000644000175000017500000000235714064326115017657 0ustar fengfengPNG  IHDRbbIDATxu0=ـn@6;A h'H6 $wq&H:8pmcN~噀9Yskˌ Yzrz`Tgp`ȟ?PoӲ{9 >JvcҳAq\1nq/<ދqR/ DD};6D\툱hʃpvFM:~*o+;AmT%#l_/ut`!8~X~ j[BaiODkZ j[Jܒ,0SHTu֮h _Iۃ.$*46±"j#3!PV(~=[B0+ 1@;(W"+8N\ZNz'] c07Jw:c?m9M"`B$ &D"`B$ &D"-|ms>83ڌnquY`=ߞ5[`G3;+WfRvVweE]xBiX \IENDB`ukui-biometric-auth/images/VoicePrint/02.png0000644000175000017500000000234614064326115017652 0ustar fengfengPNG  IHDRbbIDATxu0=l@6H6 $:d@'H:A NNX8`l¾{ R DDm?k ƊFBH7qqm8oX?QήBȗ\{ 2mc Q20-gRD7 bk2TϨú!Mh q)F4k5LD0!H"LD⁈r>F0":lM5"2ts.|жžZ2jwS^|Tۍi&e6jb?D4w=_@}e) 75<# Uڵ'(ӧk$]*1jwyh[u)ڧhTS]ɉb#8"Ԝt$"|,h, 4W@ze欝ѨA#ϳFDj.DٷuMplR6 ԀLR-h=k]d{"* oL7,ŇrbL'mP CYJM m '2F0V Gd I"LD0!H"LD0!HO|:?b6k0='tyFrmW/Cۛ5X?g?ܫIY{[]SԦva[qSz,R 7.#IENDB`ukui-biometric-auth/images/VoicePrint/16.png0000644000175000017500000000237014064326115017654 0ustar fengfengPNG  IHDRbbIDATxY0x6 p':t $ t H'L퇜b$dayxtɒy(M@0mQO^v0X5Oۤl{%>[op.uc_8c`|WދqR DD];6D\u툱ƞP6åJ}WI1+o* wK6/u`!"N+"Rgr̕1Jhu_H"LD0!Hm!fDD1!æK:u 7Tq%^d(s>~vPJ-ck) ~^_h&fKD&VWf)*O QDtn[72A#k{mBÙrSfP%3 l{DDDD!}WoD`DtED b򧑋<">#GrPևE{BX=nSj\"tҗIN fBr93WW yLl*&{Ꞩ !fVb:FY Fp?{R>Žre})Uj[v= HQl,܆9JJzМiIENDB`ukui-biometric-auth/images/FingerPrint.png0000644000175000017500000004472514064326115017605 0ustar fengfengPNG  IHDRg- pHYs.#.#x?v9iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2018-06-22T10:02:14+08:00 2018-07-02T11:05:22+08:00 2018-07-02T11:05:22+08:00 image/png 3 xmp.iid:d25dd608-d1a1-4345-8aed-f31ffb97fc5f adobe:docid:photoshop:bf20e7c4-7da4-11e8-92f2-d9e6550a8a6d xmp.did:3a170e97-9755-d640-8f8f-3f9b31c0e3ae created xmp.iid:3a170e97-9755-d640-8f8f-3f9b31c0e3ae 2018-06-22T10:02:14+08:00 Adobe Photoshop CC 2017 (Windows) saved xmp.iid:d25dd608-d1a1-4345-8aed-f31ffb97fc5f 2018-07-02T11:05:22+08:00 Adobe Photoshop CC 2017 (Windows) / 1 3000000/10000 3000000/10000 2 65535 160 160 4F 5 cHRMz%u0`:o_F_IDATxMv6dnm@ :i 4++(+(= T:hgVPh|^V4HJust; .7}Cހ坾wl叙uM1,uz뒱Wd f1,bY,X d:;NDH,FSwS8W"OTd/w/=*2)Wps C( ƴ! [݀0+@  9]n5r8L %v,vK XXcu_@ƛG1h[߁۱.b&k{q)/b^Em Ja^Xhe+q(,]WQ :. +K,lCyU[XRBTWJ<x<GJJC+W"u&/~%źebY,巸>A]˸VcZ\6ȧgƟ,Xe氟՚LH/y3C* !8׵;x&rdBJ+~'wț2nN=K8JE2r޷\YD:x&R=!jCy^ЍibDȗKW!.^5!sкTYV' ҥ>w, O@%̋ņ[e|'_ dk YIx&"۞!_ry`r@Jv4;x&3Q-R?`v9; o0з%))K] o3d_[8P2"rƼPӠqDww?n(DXHyLӆٯD1`=GqޯDLk# !uyqAք\.jaw<|+~|#8k3ynrNn*jJC @n3yq9hZ MWa2BS@TAwdܹG a]bJd}!U~* ԩ3`p:Ж,GP/g^L3#sL<ԭǧi݃㼙^HV Q>#vf%kS2 ]Yӵ}F0*" Z(b\Ur7 /Y%UAe06wW7WL׿୑o&|j͡6$$w h$5 0ԴYbLlt47)ļύ }wlvW~SQ3م I#zϖ1YLg0S佰P~Wp-bݚڡ~0N3Ɔq)4pu޹H+62#7dba|{v'=^Z*t-vDa Ҟ&[mɺ?,S,6`pU'f=`1zWN*SoILs6 k[݂uVpja-k)RX? Zq`]_ &YL@|9 i -* V5.xk0ސhpKNY ba M8n',ePasK;?`٥j9Fs0txNjnNB ִ !h 45κ-`C+@w!}o?W,Kk+,*[Z?%Kpe+:if@,fb3>4̺ksvU-mlb`ɖ2'gmTω}fOyaX5"\doDW8eu1$~e=.k,q hdh6iua,!?0wKZ-]W#~@#?ԍg4;S]:?HwhIG}4$K7i3&!E}6l^#rԏgbysv(C^jI8Fa YkCd9ޞ~ R?ҏsP.v9Ѐc7"we<i[~N)IN|:Upk67EWVzQVGХp@{!Tpmj)Χ>ul pׇb΋jeۀ->p|.;AWKXz"meրW2w<5]@=?MLV`n9tWfbG+I`c9k,aY^0l}K*,]3 >w*$1 mدD<2azm)s- NH6|SVib>˚"y`ZY| ;:s)Fp6n/@p~#u\|>xxI 53|ܑb7]QuDTd3L(^%o"9,Gfݍ֢,mVa0#M+켫>ƤyU|H Ͽ1B\$,InaMVFaہ/@T؎JvUZ|KWXVo:h\VٝhfR 3b6-sx/$hz0.x/ 4l{0 _O/})}@y}nKcA]HBKz0-|D^ao°o2Aȅh'!bY @d1,Vɕ6ij+~ X -F p IENDB`ukui-biometric-auth/images/VoicePrint.gif0000644000175000017500000003056414064326115017415 0ustar fengfengGIF89aUsD! NETSCAPE2.0! XMP DataXMP ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!  ! , &dilp,t]xzjpHl:ɨ|Zׁvz-ha4 8p-j^CWW}v"C/w5 o5X5 D352  14 +5Ҽ6̶ۻ? ?ã@ @µ{@U&*hVBS7bD6ȫ!A*Ѕ-8X@[ɗ*@J l֤UΒTMrG%yB-B(uVaͺ*vKN,Yr2H8-L6 טHu٪־$x0†!Nh1cD ,z.ccfD~tmрZH[0̧=io-m--d.@q[Nj9!ymCPA:֗K[Y ߀QU~<|wrU1z}בU{!|  }A6 "NwނMP8!u2a %aVP,ȡ؟2J!3P?HCF^"b5BQfy A2P٠IeRiX3&K9 yfbY?#[ʙdډvk9r) z&6j#QsRr꟭ΓZ+jfuZ(84ުi"+&4^*B;lٮګd ۷Ӟ. ض2L[;ۯ(&¼+0<*V" ,0LJ\2[/Ė|d.|lƹL/u2[̳, 4nv 7=O4s6/ 1P h-;-d=ji׭rS{W = t},[B<(m5}+w b03^Xy WΨóxެ]߱bSC7[CsOn?t#NN }W3{}p6X~۞F~ עәŧf|KV> ;yՏ{cWTA+NZ 0x%'@g ΁/E=BTMEݎ& B "~H [ALQU9䋇\-$'763°Tϥўɹſ⩝Ҿ^?wn>tGA"oz +f L7XPG C>4ɲˎP (R`K/ɴ$ΟWǑ7TmOkJ NW.Չ5jM5etT-;s(ڭHsr,ôlm} 'ٸk#^yI/W.ˌfu}S>l iX!Ë&ToA#TIƉ1(dI'e8Kr){>͟CE *(R .҃gӖk[ipߨmv4[ٜhSSx|[h֦3u׋~셸ףVuo]G}x")hyS4 ~J8w ^a!e!?7! ,6A`@`&fZih(p L8ފo7G<2b1c*}PWUu,-EǦ(Z("_a|b/GWy[{i[}Hh%u1=?}:bY09|wR2öƫ5ְџܪٹȿ()÷[#دቃ.TpEAPcŏ=n^ȎϤK _(eK!U$ɛ"e' P $gMCAM)ՙKcVkJ^Ta 빑X]u˓.ܦs6UlY+[v u/G.W1WLXŖ# ulc&̪Knm5ؓoamT:뾝qaւy!;l.N+ͩ>%Үx^9JGۓ?zV2oU 6'  k$ ` !! ,4A`@&dffdlB+6˯ډ 5,ʜL]rAYjke.+ ~鶊,w]G_)W}Q}Q%oz]]EY3>.<";JRg,T~ciq@k7yĺ­̧ײթ޿+#s˯7 }ϟCLМjS#ċZ#ŐSnDr|&˚0TY3"Hth.[4)N_6]tͪ@;*jѮY٫g{-S)ڷ_AXϴw"k/رkkׯ[W-\.zƘ X39FLxrؽKg&ZpjɫݶNL纳Ï^6si[d|+p!=2"ƏC#ŎAYI,WNL)3#e6C0TicM#[wgQH#dԫPƔ:PF3buЯw],Λi}UkNC{ݱmʝ>kĂJfe?fqʒ oKZGWYʈ?*1ȭq',tl\97 _k 4wUm~<WR ul//;ڹq"g/?#|ݝCu%BSc$"җi !>M8h!4h!W##q̡+b0hG|nĸ/zA! ,2Ae@&diYlj*tmꭓq:HzqI#2iHsZrRYѫvۖ^5,cY\|a w^9n]#~A}{;5ooXetI7HM#.uz5m\'D&R:P7-ĭʏ_ժХ̯߻ӱUak$p]~H ˙h1C}zgNƐ A^<$cœF6Qb2fΖ^HSgp.iTwKqYӔBE*+V\iU5ɖܪ*SMNEk֭ʑmcI߾>W>im`r">ձO)~lf͌?*2ɨI47wa.ܺqѫ?gΌ/v߳E.J1/|,觥[ʵ,>շS^^zں/|ۊdzl#EG|@Xʀb2S6wWgapiu!} !چ)-! ,2Ae@&dihfh*tm+{cμP|qI+2_HsZrROѫښ^56F8ٝeS9~y{=6}-mIGes/)u$RP|55z".8$6t*U_:-é#ε֯%Ǽy AzRpa| Cȏ=Gqƅ!"{ɒ(' TxL֔rfL"シψ bhşP ԩǞXyT dV_" VJ6We}*5l۶;2cXW jӯ`joqO|+ZD 3% 9peϊ>4/] :ϹR>?|zK䦐'ƀq -Q~ Yhjz!8!)! ,5Aa@`fh8p̊Yiﱛ@N'h5@%U2)"Z۝6<sk+E8~ܾ6kd{pX~f/uSh?QI7on&9yj(g(:Ay;)Y^0|eʽ6̶Ը@ОҾ-ØmͻӒ䲍Ph\?~ꄵ#am Zgoa 1'`k3|x Y spǓ*RMm-HQ%˚4a%1&;9R2JJuՏEVD:򩾗Wnj@ajםO{6mӳ]K6ԫh˶oWojݖel_G ׽+ϲި. Y0hʢQk:Ƈ^yrm([ι;՞Ÿ+n3pȱ@٤շ.Қ`䥬%k3.^A4Sbz9Pa†>G#ɊbxrcFcdr^KbݜaJ8'sϣ0s9(O*k4P?fjTy_ִ&(TfUhصM_r5J\][շw.4N"6ܱe8/e=xo_ͅ*"w?NƖWKnͺr/~=vnɻr}s4{Uܵ{E=:̟{v+ZYf`W^rȣq~xhӧ>|$1m\ĀEG6yb TqJRTGuf͆5ruȅW)ؕ_N! ,2Ae@&dIY*liδ&<g (eV/ٻcH&n)9huFݾMU^X]-mh8$|L~r[V#Izx%Cu<|Gio"-#3t2{Zd¶_.0ŜʥϷǘ۰-׿ܽlò湔Ɠu7!tHBv.Mb@ V_/ 36D9iRŕE(M%oV_M@WfQD"9tiOG6T(T"z*VSCFu+Y_v=+ױhݞUUph.[֣߻>xa R`3l+dȚ-s`- lsKk6Тd?}|6ܨguM{Ip-cz3sᒉ#']ou۵qONgm.=w8w<cWyT[64.L/y-4WM7\0ʪij'^%ߛ$ɿp=#7@L}Xo=tWaBVxb>0#qdÎ A_ɉ'C;eQFRD%B s(P>i};RtZ_Ħ-Ji58FsYu'UBiѮf]{rR?~۳-߳qY ~xݣzE-7_J^Ld/GNL2Jv0n!lz/dԞYk^f؜6www1X[Ӟ1lҽm-Mweac̈́\娀3g]:v\m':_>;m!WK EyK~藟dJ@gÀ;f5P QN"RX(„8q`P` ,vb4c3=8! ,2Ae@&digtm*{樂(i oF4.aɧ'sNO뵩EeO.'KfwGm];p^wx;|:e6t6mE~4}d3HjxP/$?%/#LCuV0y(&p1)ٽȬ߾شB󗏝;S"4(N^ ^ǭUE {rȎINϡǀ&8e8-3]š3}I~=m,Fe]SґT#dҬî^}JؠF5,ҵ* mY,n׻pWŸ NwnLĎ!vbOWmx*K:)ڭ5:2nV3;lǒsi6FϷ?nuMdkƳ۝}کqʒS={o}Rc17VW zŗ_C*_AmyklT !aGT|d'jqִ݈ʼn(-"12S0֨9! ,6A`@`&fZih(p L8ފo7G<2b1c*}PWUu,-EǦ(Z("_a|uW]gD{'DbyS&\yibr|5T}:%%0?nHżvЙј؅Vˬϻܪ·FR)y;U9xݩ`?I!{b˘ϟz؃#A A6n"ɖE%ˀ0_i͞.s0F*mb9t#S~ 5ѫ:))SPSbmNBJ(ڪ)-JWj=S{&K.Ӽ['&OrَԬR綝pVv7k̎CZ ~ [آ%6Xˈou‹Qf,K[% 詋?uY9啳W>\xoCoX#sT=W=` aeD8ńU M/c"8X'Ƌs4H! ,3Aa@&YlB+*6J 5,ΜL]r%q*mA[+~fe2f6-/g=H{#a;}&Qqx]VH0%7$EsknWp3}@~<>M@Öƍ7.ΜJѾڤ"XŴ#̙ÆN?}#]}GAy 6KXB-bq;$4P;!=FL+]ғfʚ;}N>_Ø/dU˧,).ڴ%ҌPͱtzlVhI-k4nI(^nמA֪~[8a{{2䙐A6VUN-e&^XjkzZkgk+,.64sEAx[pl.74r]Nb0U3ыwz廗o{;j䯍s-˷{{sM?EU&`w-2aoaH`PX jLXdžu V(rH!y+F! ,2Ae@&dYfhfl[fz< P_&{&NɔҞΔFְ_U^Wb֣p3yD{R}cgMxdu'@taK9l#-p4qUX+~&$ħ<ʣP̰©'\ǃ܅w^nE0!à "4EאbGy $d$Ē2xrݥdeKOfOisg?2XRtӐ*5hLZ5'Sը%jM߶tۣ3 ݊Wu.i #+^+82Y;~X]"3嬓bbӢ>U֯=>\uVE2ԅ]OVܛ8цC79˰eSC!@'<=mS汞U>fG>.{帧\vǝIuHz $1{ 1% NaFHۇ rh!|fDbDžԹ,b=+/q#sƎъ!;ukui-biometric-auth/images/VoicePrint.png0000644000175000017500000000252614064326115017431 0ustar fengfengPNG  IHDRg- pHYs  ~IDATxAN@MP"n(a}.`A Y4]|H\ >AD RqObB#ϧ3ۻ_ }G36[ 1A@@@_r-@ @@@@Tt()RM`RF%,J͊R#n/XࡤdoEyQjm C$8vC-f>I}#IWEiQmWY]}D<\ VT,U_N>]u8qѰBB0p %)9"sI02 `4 ?-% ƃ{BU1%\򊒱B̷bhDRR3R@*Eh9+]\xQ0"F@(x}h/nj/oht2h r /-``ˊnB@K|&@@@@:)B 4 M݄L G"n1l"%~K$tZE6ϖ;%Fn϶( Ig#V]Q}]IYٍztt޾]R6wO*0M\%A)X25(Aj#ДA6\nlsg1_B]wddF!!ݡΧ\vyX@[&em_# o M Uגr/D: E!˰GS%z_..B]`"$tB R~b*ЄP}1k~\e RU<撫]E Xt5sȍK!` *I_q@ 6gD@@@@@}{,CIW$ڍꂮAX~R#oRGrL}IOGA$إ`_6^B@яEU@nJY`Wj;}o_k|Li_w@&)>a$BHv%2}}~m5E!s-&HP7b]$Ur`:@@@@8c@Z**`@@@@@@@@@@@@@@@@@@/6Zm[Hd|"%yAIENDB`ukui-biometric-auth/images/Iris.gif0000644000175000017500000005671514064326115016247 0ustar fengfengGIF89a2nuw.SMlS iPpZ+폢ԩH xÓv[b%Sөς.vBSKLHwd06d,ۻkx2a؉kܦڙ۞y”c~RJ>kD! NETSCAPE2.0! XMP DataXMP ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!  ! ,~qqt}uu}tp}ƽss@@rϬoܧtݧoM)Ψs)@qf+fN:~3'ZCi@lP$;97Nz#/x%#tYj3izs/\:Sz GePA 8(9:t Qެ̷Tg}ú&ѫ0DKVQ}R}4\׶$j}TYSə;Q@2K YcK_ VeLsnՙϘj>| ӨSǚ>cTeu&]Aߔc*s䞜/,J5&? 7Ucų{Rw'jMeNJ1ɤ3!adq' )o ` >52MJ[A8@(R9Eay s[) Dpw nB"rC"@({gb pthf1uMxIuW6Xvf>N9PG.Dw$WI-#&F%x% "O>eC$$C}H@J!Ni%X Ǥh&MPĝ*B#QX` q6(¡eYGp=هqP_QMX$:ȕ#J~񚏨"q H'i!dh\reA">GƧ >'}@|X\)0Y{Htdɭ)O&mlQ 4" +j~&2ty"uNӣT)NIsUB:?원KPszYy$/0{;.${Ew/$TI. wHaJ7:ξ"ȌՃHK57~^]$ jȏ#wR?4ow"Q!0cNPcDax +$A? oEeص h"&ԝa*t[;G$p5‡n;2b$c "D 7a3+C|( E4ȋ-/3fP#'fLA#! @BvM-% DJ܄tBu'MF01C)UB:Ut%#JHj`"(\a"'Qڨ1Y>xla/<&"G ǤȉP 0\#3M3/q7o;aD9N|cdD$yi8QҺKCTch6وfBUDFC4lX<iiTÄ}(zM5KMO:Q!F"{hXW"+Yj"G,g.SZDaFXhE}HPFǘ3))A2"P Cp"QS;6{<@ y؝Lp]=(zȘM ) @Y0q"qqDo gT&:"4@+B|2Wi 1C0nzp%b[i#QWnJB)=MQ+=^"&٫}wE"F{-kSCa/G& q!"]0ȻɰWD@!^I>7\l׉q{5ڡx+\ E^4H@?* @8ePySի&jU|U.$X?DMw BY I4xP7UMV{0|3t Χs EVQuv };spYgm!`H")b97~{km0Y2w`8#Tq֣z@&'$6 lf!vؤrE'b uq`2TEFCT4E&PP;5F^*+FkĨFz;{FK8d ,Š+uŶQA0(c7E\5z,0,1byYˆSZHP& ! ,~~0̅o͵}}rAAA}|J7lw(!#Jذ(e6ߧ82 ȉk 4XKbʜĊ m@̣9!- FAk(- $F}BUR|aN ;;$ EF!(:3Ԫ"߿}ꥪUKb&6Rٳh e໥t+ȜD_CMР~pK^c ch'<\ rW4.ȓXμO;ucHȓy^.čP܅˟IOu^3O52IDQpY@^p-EUz2E{q (!sןu&&`>j #PG%pB^qrG*PFd*,)}(u"FXGVubH()9҄A_\3* JBYW>hӭeXp$Т[U ޞJ砅꫰jhS2 A%m`l~_%*=TT鍆2 h +t¶rz r ]G# ٬§6m%,hćkFlݕ 0䡱5\yB|T{<#+8@B'KPG]8T],SJa#AsLr1 hGn,(.[9C{Ѓ='xLG.D 5FLMXguB 6 3Dkhc녤p! ,~~„0ūöǿӤAAA痰)c (1(TȠÇ.\0<|)%T r;e! (SK0!NDx/e?yD m#%P $&}´SJTP!M 67N>!u'Õ,6-pʅ۶-S-SJp6:Ƒ g+\n\#LȐ}4/ʽrK>oV(•L)*X萣ULqaovf!_ItR &NKl&OYCßΫ?},fL1P2rl2on5蛥M2$}X։HڽRZL}'Cm]0Cya%t q}ƙp_~ǗU$uX _qG$sa#s8r]P% R6ax]!"F)`b}*ʐs4$M`RXv%5tdwYm*t$1 {w@ȱ襋G ]ɠYo& œ&LzSC 6稤jC *%@D%( ) >w&B b~F;=t0喜}mDߝACv ̠,}>½/~.+o vz!IG 2MDyAhW>!j(qPAkiz#r: !8 h5<x`=*S' 2 +n` ;~M\#1|5HhNQ !t1 1|ix@{<Fa8@7ЀGyFPNJ;tS Fu5hL ! ,~~„0ūöǿӤAAWWee(77/:aEi'Ar]NnFrʏL0ȱnjL^(ĉz !*P5|Mb ϟLr'NTrö'Npf80Я`?$(VNh TbBjֲNP|  4X B`9r] c*=vZrm=$!<VBëǾ@Dkc˞} ĩ6⇘ \rfIP9unht'75Dbw݀sȚҹus|9Y*bFXEWG ݁ $ p u ULp ge-gJ#rabt\ՔtAu]<@#~嶞'h}X\ ppL@`)rV\?иXh *h t n.G!ed(uc't\)tMZEC_~F}f@) jèjs uq /^8iIx[xpV ,žv)B[*vgpFF_V؊LXbP_/[DPm詨B ,P Naov&8AzphLSUeWtZfKD |o.ۯ0𳤂zA2_&{"9<2U1V>B\Bd 'tF0FaĿ+t!}w|;߀mA` bqJ!Qk5;J3(m}ܼsP@4АOHf&əzwB'?jʣ`ě]vه'aЫ@To C@jɷ9! ,"~~5 5l5- | iϹ͍H|-ҍ5 ߡivv 755aYU憂|)@䝼gj' !}eZQǏ =N$L7,$ 3iIIc`2c  Jh  @A6s/$etϠQb;ٳhӞ%K6":P0Te00Ud $rmBGi+(^xǐKNK6ˏQ_[{B2v27#qc$b~Bm۲eGf|6@0sO }" a–bٵEhoN[ xϞwbqtaPdz=1w2h &yO](Y؈qh&Q/Q`Y($t <Ślp&Aډ acIb# E╫e]7◂UGq iBp*xth'>ᄘ?'\h#X>hG逯#]t:< V;"ccN& | @冫cc4d*Ck b * Ҫ $`j2 2Al2b/qkI ZD_[lƾ)ժ aF) ?  4ϱ j=GN=K+%-|B\*/x  nxRa `p@A XЂ#Ƞ#V0B(4aRB0ܠ eA< .PBppV{ ?!@@@2lA*\ H x1fPttQM' =LKk[bԱvd0 ̡y)4 Th@. W"P<! ,.~~l||--H±H 5̩5| ō՘l зߟ-i煴 0%3푸d ѻ7Æ"JHC|EJ-ۤ^Zch!E AXI͛3 -h)dH)I (ffeׯ]jΉ<烧FR'$y-ڹ"j_+LF,!@c7=6ڵAhνv[><8,$;# H5/OA8UaOǝ h&`v'W705#\&WI7A_DBL0Zv`4x c<Ё 5ָ`څa` QY׈MVY"-&hg %pH PBD \'axm3E{XF (ѲCʍQq/(v. %jꩨ؉|I^>*&IRZp&h[1PABev!.1 2Cr#zg4H9xA\aXF-vܤTr[VlVx0# .*hp !t:n&P&ˇl2l2i+%& )@~6 HC7 !djg`x9%0DBQ `XW"ij8 ; 6C +PK U_-HCLd$>io,T̗^͝D@y =:|46G [x!8 ïG#4?!'@ Ӡn o0`GP}!t[DA\ŕ>t/_p RlZV0A Ax <. {P=*܀?\%&A ޷'  P"T"( e( @brΐ.zы*bU@2QD/ 2aE/,(;,҂XI! ,4~~ll|H5||~͖iԶѳڅɲ 0µ۽H- /qH$'o|<@ AXظK7B6\Fvqzj8gFQb:4K (]T),Drs0*f%T(DU[mۦpҀvڨA7/X;|H 0Q(n+l< ,q37!kbDP8N;!Lh12i㡐RLoE @<@kx@Cʼn3!NDoޞŐWGm̭kH-7[ɕ{? .}2OAv]q4u$PQ[`A v#MPB[V}`‰&t" 10C `Be z#YU /`IYwJ}%bt٥ Hc#i3`7ʐueR @Uiǚ0˄$Rh$zihP(,Ce"bi*zid,i6!x=x*& ]nyb~s8SmF'L3G rc/,EDoWJJ)_jzs27%`[Ъ %pG_~r:rHpUHzM L,^b:m*7C,j>}ѰQ5dx /!.^)C&3 خ CG `1 uמɻD :8{?,EÈVz91MD]7!`z 8TȝCH d!e4cX ű6A=G  !8믯ݪN'n|x; (EEZ>PJ G'>_FA+{`;yK`9~z@ '!!|j JF" a( b$#(v|D񩒈 HDd*8*vAV%2HXAFa! ,:~~H |  HǂĞˑ5lؖ-ґqߎܯ턏| 0vv7(VKqC>yε2Ii|e'hx%_(9 )3E{СN2}Ed  Ă20qHӧ"@P ?]„O65}ZOό5j![ p2x x=CiRQU#Fd)Vۧʠ*[ 23s&sM4i,@ .F 5 !_+BC,Gs ȑXNBDs:u*TvYsׁ-\;Nƺ Hc kc99'ED<  <7Frt\BJvV`''AQIpfGB~ן ,`(1Ƌ,r9]H}TV/e^'%A ͷY, h•&teH`v# =V !ER@0D^hQo@>F> $A. [BPЁv ;H6QF0 < 6 4A *ChDt`qЃT. @! ˌ[""5Aw*(x'>~ZE"p2@21*@#U6` o0C%\@ x ŇC'LQ^xxCdE+KC! ,@~||VV U vU×?͢м|?U77?vHvVMXЎC;K"JHqH $LAxjDRP!''\9NGbʜIȒ |8PܯY>)ܩ(!i ,py XkDA5I{K(e"}04ʦF.w4`䅋 L U+eOH5 H5ڮ;]AW=_&4^ͺ9 [7*Q"n̴sϡIW9 Nxp`ρ{kwZi&c*fp-Q49F=a7>l4B \`{v{H`<4 47A;tO8쁃'<B!pJ!nx+VX`GA,HK@ :,u{ %(4( ȇ {Syz{^}Ѓ4 Wh v0 @O @܆HoJ -@ buP,IZ` Jb qWF\AhL4Bu”.R1 @_R(@ TD?! ,F~|| Hlâ-;Ȭ%A,Sfk9xx{r1b/YS0f4 ǸA^:54`Ë㰓 W> @IGMwyIe:m@ 0h 6x9DN<1`WYX`d}V6SWөހO&~Gp/̈;L /bBOL7BwPtwyPaU'{Hˤ P1$!6 jVVؖ]:C/݆Ӏ4Ewc cMɗ!a"~@J ODYnF/&P  !< +8 /x!0gR =B_j!>ep9Eh9)@s`.::FJPXЁ΀v8H '2C^<@A Oxk z|@#xV p|k0Hin0""ZPPI؂ Z@E Xbupx` u02ha %X a{bB}hBD`@! ,L~~|| H U V×Vȵˡ?Ԕ<َ7Β뜐7KKvlﷰFe@ŏ*GHŋñ~ n#`Gc82&͘_4h`'̄ -!IZtAqKe˟$Hݱ.jʵ׬4T",ԖCv6|< x$C L8 L$ƀ!JAdYju1(QXc vkp4cxycf͆ yM@<νydžynBv 9ls'谳(1@y@Dx<F(a v7CpOH`z5BUM&[OQ ҥw Ä<6! wX aT&wKhUqڀDC  3l# DtKk [,Ո'>uن0*p _СپlڃLѵ,iAs9`ҁq V^50suvaG9ocF)H DRۉJ$ BC{ {?SL<@FFпկ~886xOnpN\#_={,!CR!Api}g@HA7X 2X(RbzmTE8X7up|O?OawE HDL!PH=@$,PH9l"! ,Q ||~~;5 VĞʽ̽ ӎV|˜ܖٿ(( 5;KC WWi ǎ*hȱǍh ō*!_F{vM4G.*F &tM'EuK_Ϯi&}!ԅٳhӪ]@Ҥ?,ͨ؀J \002kp(W0QLǐ#K , &dp`BaO|+@௅-̠6<|`O{>YEnf9JaeH.5!u[XlpCBôm'a9_Ͼ3c!Qx-x)T{M`8M[ Ex $W $B*bisbPs̸I z-96TndvqH_-W]`$`+6Æ$١F`B6\ȗ92k944E}I2I /P!J(qT~53HB2 T`=X0BA##X:( w nAG2(Sw) Cݤ)[( ٗ =P_A#tQ``/HF  @b UHP ,ȁspᏡKgBC|D ! ,W |~~|;őU|̾5? (HѺߗܹ vU״Vi􃰤 7K H0L;T\B>oh# CI2Fe H"m"b֐C]UL@( H-$KW+ZVN3j ,h pʝ;S&@ BQQw\)<T}D@&38ϝ׼Ȍ Ӕ)KN0DE(F +d 9{$_ ʆ f (Y vmA`ltGZۃ_@"?@5< 3H_e OG|iz4uTy䢞cemPV[,gp4_Nc 7_p 1{UHq^'|XVTifG #2ti—S`ŗhv)Î,6cVjQeUyp0Jb<IAepZr]4j̐CPZ fǥt.@j@gm>GfUN蝑+҂83F2|bCf苋(. ~٥gi 0,, A.Up^ :.zv6*hLuꨍj+ä7-wnvrع`" G '^Gp!] /`6s7ߌzpk Ă>J_aQz&CB™1?/t:Ǡl / 6xQH F hQۇe zluG̜}06 gy:wМ@1f^Sd;PhM߰ p6l9+' PBS-nFfA1WYa9J\ ?pBS0#3<!p@:'#T4WP āN@?*\@9H PH5`:~H'@ dA*d ' p=AoF"0XAxEN42A@F_EHB*J :5xa8#g|! ,] ~ |||7 s~ě-|7f0[VZIW܈~J0%L>%H$̎XܡB` +$%<ON b(x1qI& ŠF5Oln^ B@+9 ÊҰEFn!  T^D|I&?º%"//I;휗|(# PT",誂3, $L"ngPz'`7!c-A_3Wa.~%`Xcmrz % KdL/6ďor$^  # Sl Rmng]r]za;2=nf%Av`0B@G $ `nՋ@C 4*Ě.syTG ED{2n!`@0ax!p@K@#={0PT& kj`<$`{ X/KQ59xAvC4{H%8G~k x}AY`! ^$Є)Y ! ,c|| v~H| ~5 -Ğ~ iԎlH-˪ -ٷ離l|ݫ50BHs/Z>bKq2j(Ǐ 7j4+Cp`5.Q#H AXɳϟ;ܔĊajZ+`ؙ¦Gꪬv. ']E_%}p:1i`:+!G(yx>P*{n>*f7@@~hy, 첮|bG wod;w˪ Π6tqo d&ao,3qo:-@Q>V9|9qy^|.PC뾊k0dP"3͢9[}&nh54k1Kk{GUB% kad/Z6C]j,jzkv@2my z? C ^k1o%^8Wo,A3NA(̀>J(qPA 0B=P~Ax o!8B? h 8H =*p/{B! t$?$O/)h`DOzw=!A J6avUbZF`Fǿ!@T@u{",Z Dl! ,i~~|é-|˕lH l֝Ұ ޅ|50l| H ϑ݄JXȰÄA@0N~Jױmm B˗0YA)!a ;vZAp8nz9G%םdeFe@իUJ}̅aD\I~!W $M (UiW+ݻw߿ ̆[ĉC5Nk} m1NWڝZ/ $B~BiӢEk5S.?n"Cb;ej_KXУ?gΜ{`A$WI?I0Nr{&/; u27]uOf L${VĐxAY'A@,造 5~ua)x": pazWɄUT06&GA ( TiX0 +h,$dEv `M5(ǝw yqYCc:fkхY>裐F )TAfʤ^TiB=Fb'}Yy@}HttW }D`9аU j**C%PB@ -j؃r:Rt&$ gИB1 l,p ӆA]mjHj׮f}"+]@C 3o1ls +B Shb&Ll) !T"&P.j@kP\w}-*x+bWɥes ٞ^HqTI!zWn!J\:T 8N0>; ?. * **/ #include "generic.h" #include #include void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { Q_UNUSED(context) if(!enableDebug) return; QDateTime dateTime = QDateTime::currentDateTime(); QByteArray time = QString("[%1] ").arg(dateTime.toString("MM-dd hh:mm:ss.zzz")).toLocal8Bit(); QByteArray localMsg = msg.toLocal8Bit(); QByteArray prefix = logPrefix.toLocal8Bit(); switch(type) { case QtDebugMsg: fprintf(stderr, "%s %s [Debug]: %s\n", prefix.constData(), time.constData(), localMsg.constData()); break; #if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) case QtInfoMsg: fprintf(stderr, "%s %s [Info]: %s\n", prefix.constData(), time.constData(), localMsg.constData()); break; #endif case QtWarningMsg: fprintf(stderr, "%s %s [Warnning]: %s\n", prefix.constData(), time.constData(), localMsg.constData()); break; case QtCriticalMsg: fprintf(stderr, "%s %s [Critical]: %s\n", prefix.constData(), time.constData(), localMsg.constData()); break; case QtFatalMsg: fprintf(stderr, "%s %s [Fatal]: %s\n", prefix.constData(), time.constData(), localMsg.constData()); abort(); } } ukui-biometric-auth/common/generic.h0000644000175000017500000000275314064326115016453 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef GENERIC_H #define GENERIC_H #define BIO_ERROR -1 #define BIO_FAILED 0 #define BIO_SUCCESS 1 #define BIO_IGNORE 2 #define BIOMETRIC_PAM_DOUBLE "BIOMETRIC_PAM_DOUBLE" #define BIOMETRIC_PAM "BIOMETRIC_PAM" #define BIOMETRIC_IGNORE "BIOMETRIC_IGNORE" #define BIOMETRIC_SUCCESS "BIOMETRIC_SUCCESS" #define BIOMETRIC_FAILED "BIOMETRIC_FAILED" #define BIO_COM_FILE "/tmp/bio_com" #define STR(s) #s #define GET_STR(s) STR(s) #define _MULTI_THREADED #define AGENT_NAME "polkit-ukui-authentication-agent" #define POLKIT_LISTENER_ID "/org/ukui/PolicyKit1/AuthenticationAgent" #ifdef __cplusplus #include "qlogging.h" extern bool enableDebug; extern QString logPrefix; void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg); #endif #endif ukui-biometric-auth/bioauth-bin/0000755000175000017500000000000014064326115015570 5ustar fengfengukui-biometric-auth/bioauth-bin/CMakeLists.txt0000644000175000017500000000124014064326115020325 0ustar fengfengproject(bioauth-bin) set(CMAKE_AUTOMOC ON) include_directories( ../common ../bioauth/include ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ) set(bin_SRCS ${bin_SRCS} src/main.cpp src/keywatcher.cpp ../common/generic.cpp ) add_executable(bioauth ${bin_SRCS}) target_link_libraries(bioauth Qt5::Core BioAuth) install(TARGETS bioauth DESTINATION bin) file(GLOB ts_files i18n_ts/*.ts) qt5_add_translation(qm_files ${ts_files}) add_custom_target(bioauth-bin_i18n DEPENDS ${qm_files} SOURCES ${ts_files}) add_dependencies(bioauth bioauth-bin_i18n) install(FILES ${qm_files} DESTINATION ${UKUI_BIOMETRIC_DIR}/i18n_qm/bioauth-bin) ukui-biometric-auth/bioauth-bin/src/0000755000175000017500000000000014064326115016357 5ustar fengfengukui-biometric-auth/bioauth-bin/src/main.cpp0000644000175000017500000002176514064326115020022 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ //#include "mainwindow.h" #include #include #include #include #include #include "generic.h" #include "keywatcher.h" #include "bioauth.h" #include "biodevices.h" #define START_COLOR "\033[1;31m" #define RESULT_COLOR "\033[1;31m" #define PROMPT_COLOR "\033[33m" #define NOTIFY_COLOR //"\033[37m" #define QUESTION_COLOR //"\033[1;37m" #define RESET_COLOR "\033[0m" bool enableDebug; QString logPrefix; enum MsgType { START, PROMPT, NOTIFY, QUESTION, RESULT }; enum _Option { OPTION_TRY_AGAIN, OPTION_SELECT_DEVICE, OPTION_CANCEL, OPTION_UNDEFINED }; typedef enum _Option Option; static QString lastMessage; void showMessage(const QString &message, int type) { // filter out the same message if(message == lastMessage) return; lastMessage = message; char *text = message.toLocal8Bit().data(); switch(type) { case START: fprintf(stdout, START_COLOR "=== %s ===\n", text); break; case PROMPT: fprintf(stdout, PROMPT_COLOR "%s\n", text); break; case NOTIFY: fprintf(stdout, NOTIFY_COLOR "%s\n", text); break; case QUESTION: fprintf(stdout, QUESTION_COLOR "%s", text); break; case RESULT: fprintf(stdout, RESULT_COLOR "=== %s ===\n", text); break; default: fprintf(stdout, "%s\n", text); break; } fprintf(stdout, RESET_COLOR); } Option showOption(bool showSelectDevices) { QStringList optionList; QString message; optionList << QObject::tr("Try it again"); if(showSelectDevices) optionList << QObject::tr("Use other Devices"); optionList << QObject::tr("Cancel"); for(int i = 0; i < optionList.size(); i++){ message = QString(" %1. %2\n") .arg(QString::number(i+1)) .arg(optionList.at(i)); showMessage(message, QUESTION); } message = QString("%1 (1-%2):") .arg(QObject::tr("Choose the option")) .arg(QString::number(optionList.size())); showMessage(message, QUESTION); char line[1024]; fgets(line, sizeof(line), stdin); if(line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; if(!strcmp(line, "1")) return OPTION_TRY_AGAIN; else if(!strcmp(line, "2")) { if(showSelectDevices) return OPTION_SELECT_DEVICE; else return OPTION_CANCEL; } else if(showSelectDevices && !strcmp(line, "3")) return OPTION_CANCEL; else { showMessage(QObject::tr("Invaild response \"") + line + "\"" + "," + QObject::tr("authentication will be canceld") , NOTIFY); showMessage(QObject::tr("AUTHENTICATION CANCELED"), START); exit(BIO_FAILED); } return OPTION_UNDEFINED; } DeviceInfo showDevices(const QMap> &devicesMap) { int count = 0; QString message; showMessage(QObject::tr("=== BIOMETRIC DEVICES ==="), PROMPT); for(auto type : devicesMap.keys()) { for(auto deviceInfo : devicesMap[type]) { message = QString(" %1. [%2] %3") .arg(QString::number(++count)) .arg(BioDevices::bioTypeToString_tr(type)) .arg(deviceInfo.device_shortname); showMessage(message, NOTIFY); } } message = QString("%1 (1-%2):") .arg(QObject::tr("Choose the device")) .arg(QString::number(count)); showMessage(message, QUESTION); char line[1024]; fgets(line, sizeof(line), stdin); if(line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; for(auto ch : QString(line)) { if(!ch.isDigit()){ showMessage(QObject::tr("Invaild response \"") + line + "\"" + "," +QObject::tr("authentication will be canceld") , NOTIFY); showMessage(QObject::tr("AUTHENTICATION CANCELED"), START); exit(BIO_FAILED); } } int deviceIndex = QString(line).toInt(); if(deviceIndex > count) { showMessage(QObject::tr("Invaild response \"") + line + "\"" + "," + QObject::tr("authentication will be canceld"), NOTIFY); showMessage(QObject::tr("AUTHENTICATION CANCELED"), START); exit(BIO_FAILED); } int i = 0; for(auto type : devicesMap.keys()) { int size = devicesMap[type].size(); if(i + size >= deviceIndex) { return devicesMap[type][deviceIndex - i - 1]; } i += size; } return DeviceInfo(); } int main(int argc, char *argv[]) { QCoreApplication::setSetuidAllowed(true); QCoreApplication a(argc, argv); QString locale = QLocale::system().name(); QTranslator translator, translator_bin; QString qmfile = QString("%1/i18n_qm/%2.qm").arg(GET_STR(UKUI_BIOMETRIC)).arg(locale); QString qmfile_bin = QString("%1/i18n_qm/bioauth-bin/%2.qm").arg(GET_STR(UKUI_BIOMETRIC)).arg(locale); qDebug() << "load translation file " << qmfile << qmfile_bin; translator.load(qmfile); translator_bin.load((qmfile_bin)); a.installTranslator(&translator); a.installTranslator(&translator_bin); QCommandLineParser parser; QCommandLineOption serviceOption({"s", "service"}, QObject::tr("Sevice Name")); QCommandLineOption displayOption({"x", "display"}, QObject::tr("DISPLAY env"), "display", ":0"); QCommandLineOption usernameOption({"u", "user"}, QObject::tr("User"), "user", ""); QCommandLineOption debugOption({"d", "debug"}, QObject::tr("Display debug information")); QCommandLineOption deviceOption({"e", "device"}, QObject::tr("Device short name"), ""); parser.addOptions({serviceOption, displayOption, usernameOption, debugOption, deviceOption}); parser.process(a); if(parser.isSet(debugOption)) enableDebug = true; else enableDebug = false; logPrefix = "[pam-diaglog]:"; qInstallMessageHandler(outputMessage); QString userName = parser.value(usernameOption); if(userName.isEmpty()) exit(BIO_ERROR); qDebug() << "authentication user: " << userName; uid_t uid; struct passwd *pwd = getpwnam(userName.toLocal8Bit().data()); if(pwd) uid = pwd->pw_uid; else exit(BIO_ERROR); BioDevices bioDevices; DeviceInfo *deviceInfo = bioDevices.getDefaultDevice(uid); bool isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton(); if(!deviceInfo) exit(BIO_ERROR); if(bioDevices.getFeatureCount(uid)<1) exit(BIO_ERROR); showMessage(QObject::tr("BIOMETRIC AUTHENTICATION"), START); if(!isHiddenSwitchButton) showMessage(QObject::tr("Press Q or Esc to cancel"), PROMPT); BioAuth bioAuth(uid, *deviceInfo); KeyWatcher watcher; QObject::connect(&bioAuth, &BioAuth::notify, &a, [&](const QString &msg){ showMessage(msg, NOTIFY); }); QObject::connect(&bioAuth, &BioAuth::authComplete, &a, [&](uid_t uid_, int result){ watcher.stop(); if(result && uid == uid_) { showMessage(QObject::tr("AUTHENTICATION SUCCESS"), RESULT); exit(BIO_SUCCESS); } else { showMessage(QObject::tr("AUTHENTICATION FAILED"), RESULT); Option option = showOption(bioDevices.count() > 1); switch(option) { case OPTION_TRY_AGAIN: bioAuth.startAuth(); watcher.start(); break; case OPTION_SELECT_DEVICE: { DeviceInfo deviceInfo = showDevices(bioDevices.getAllDevices()); bioAuth.setDevice(deviceInfo); bioAuth.startAuth(); watcher.start(); break; } case OPTION_CANCEL: if(isHiddenSwitchButton) { exit(BIO_ERROR); }else{ showMessage(QObject::tr("BIOMETRIC AUTHENTICATION END"), START); exit(BIO_IGNORE); break; } default: break; } } }); bioAuth.startAuth(); if(!isHiddenSwitchButton){ QObject::connect(&watcher, &KeyWatcher::exit, &a, [&]{ showMessage(QObject::tr("AUTHENTICATION CANCELED"), START); bioAuth.stopAuth(); exit(BIO_IGNORE); }); } watcher.start(); return a.exec(); } ukui-biometric-auth/bioauth-bin/src/keywatcher.h0000644000175000017500000000201614064326115020675 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef KEYWATCHER_H #define KEYWATCHER_H #include #include class KeyWatcher : public QThread { Q_OBJECT public: explicit KeyWatcher(QObject *parent = nullptr); void run() override; void stop(); signals: void exit(); private: struct termios save; }; #endif // KEYWATCHER_H ukui-biometric-auth/bioauth-bin/src/keywatcher.cpp0000644000175000017500000000361614064326115021237 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "keywatcher.h" #include KeyWatcher::KeyWatcher(QObject *parent) : QThread(parent) { } void KeyWatcher::run() { // 修改终端属性,保证按键被立即接收 struct termios current; tcgetattr(0, &save); current = save; current.c_lflag &= ~ICANON; current.c_lflag &= ~ECHO; current.c_cc[VMIN] = 1; current.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, ¤t); while(!isInterruptionRequested()){ fd_set readfds; FD_ZERO(&readfds); FD_SET(0, &readfds); char ch; switch(select(32, &readfds, NULL, NULL, NULL)){ case 0: // printf("select time out\n"); break; case -1: // printf("select error\n"); break; default: // 'q' | 'Q' or Esc if((ch = getchar()) == 'q' || ch == 'Q' || ch == 27){ tcsetattr(0, TCSANOW, &save); emit exit(); } } } tcsetattr(0, TCSANOW, &save); // 恢复原来的终端属性,以免干扰shall和之后的程序运行 } void KeyWatcher::stop() { tcsetattr(0, TCSANOW, &save); requestInterruption(); terminate(); wait(); } ukui-biometric-auth/bioauth-bin/i18n_ts/0000755000175000017500000000000014064326115017055 5ustar fengfengukui-biometric-auth/bioauth-bin/i18n_ts/es.ts0000644000175000017500000000636014064326115020041 0ustar fengfeng BioDevices FingerPrint Huella dactilar FingerVein FingerVein Iris Iris Face Cara VoicePrint Impresión de voz QObject Try it again Pruébalo otra vez Use other Devices Usa otros dispositivos Cancel Cancelar Choose the option Elige la opción Invaild response " Respuesta interna AUTHENTICATION CANCELED AUTENTIFICACIÓN CANCELADA === BIOMETRIC DEVICES === === DISPOSITIVOS BIOMÉTRICOS === Choose the device Elige el dispositivo Sevice Name Nombre del Servicio DISPLAY env PANTALLA env User Usuario Display debug information Mostrar información de depuración Device short name Nombre corto del dispositivo BIOMETRIC AUTHENTICATION AUTENTICACIÓN BIOMÉTRICA Press Q or Esc to cancel Presione Q o Esc para cancelar AUTHENTICATION SUCCESS ÉXITO DE LA AUTENTICACIÓN AUTHENTICATION FAILED Falla la autenticacion BIOMETRIC AUTHENTICATION END FINALIZACIÓN BIOMÉTRICA FINAL authentication will be canceld ukui-biometric-auth/bioauth-bin/i18n_ts/pt.ts0000644000175000017500000000640114064326115020051 0ustar fengfeng BioDevices FingerPrint Impressão digital FingerVein FingerVein Iris Íris Face Cara VoicePrint VoicePrint QObject Try it again Tente de novo Use other Devices Use outros dispositivos Cancel Cancelar Choose the option Escolha a opção Invaild response " Resposta Inválida \ " AUTHENTICATION CANCELED AUTENTICAÇÃO CANCELADA === BIOMETRIC DEVICES === === DISPOSITIVOS BIOMÉTRICOS === Choose the device Escolha o dispositivo Sevice Name Nome do Sevice DISPLAY env DISPLAY env User Do utilizador Display debug information Exibir informações de depuração Device short name Nome abreviado do dispositivo BIOMETRIC AUTHENTICATION AUTENTICAÇÃO BIOMÉTRICA Press Q or Esc to cancel Pressione Q ou Esc para cancelar AUTHENTICATION SUCCESS SUCESSO DE AUTENTICAÇÃO AUTHENTICATION FAILED AUTENTICAÇÃO FALHOU BIOMETRIC AUTHENTICATION END ENDEREÇO ​​DE AUTENTICAÇÃO BIOMÉTRICA authentication will be canceld ukui-biometric-auth/bioauth-bin/i18n_ts/zh_CN.ts0000644000175000017500000000764614064326115020443 0ustar fengfeng QObject Try it again 再试一次 Use other Devices 使用其他设备 Cancel 取消 Choose the option 选择选项 Invaild response " 不能识别的响应 " authentication will be canceld 认证将要被取消 AUTHENTICATION CANCELED 认证被取消 === BIOMETRIC DEVICES === === 生物识别设备 === Choose the device 选择设备 Sevice Name DISPLAY env User Display debug information Device short name BIOMETRIC AUTHENTICATION 生物识别认证 Press Q or Esc to cancel 按Q或者Esc取消 AUTHENTICATION SUCCESS 认证成功 AUTHENTICATION FAILED 认证失败 BIOMETRIC AUTHENTICATION END 生物识别认证结束 ukui-biometric-auth/bioauth-bin/i18n_ts/tr.ts0000644000175000017500000001136314064326115020056 0ustar fengfeng BioDevices FingerPrint Parmak İzi FingerVein Damar İzi Iris Göz Face Yüz Tanıma VoicePrint Ses İzi QObject Try it again Yeniden Dene Use other Devices Diğer Cihazları Kullan Cancel İptal Choose the option Seçeneği seçin Invaild response " Geçersiz cevap " authentication will be canceld AUTHENTICATION CANCELED KİMLİK DOĞRULAMA === BIOMETRIC DEVICES === === BİYOMETRİK CİHAZLAR === Choose the device Cihazı seçin Sevice Name Servis Adı DISPLAY env EKRAN env User Kullanıcı Display debug information Hata ayıklama bilgilerini görüntüle Device short name Cihaz kısa adı BIOMETRIC AUTHENTICATION BİYOMETRİK KİMLİK DOĞRULAMA Press Q or Esc to cancel İptal etmek için Q veya Esc tuşuna basın AUTHENTICATION SUCCESS KİMLİK DOĞRULAMA AUTHENTICATION FAILED KİMLİK DOĞRULAMA BAŞARISIZ OLDU BIOMETRIC AUTHENTICATION END BİYOMETRİK KİMLİK DOĞRULAMA SONU ukui-biometric-auth/bioauth-bin/i18n_ts/ru.ts0000644000175000017500000000705514064326115020062 0ustar fengfeng BioDevices FingerPrint FingerPrint FingerVein FingerVein Iris Ирис Face Лицо VoicePrint Voiceprint QObject Try it again Попробуйте снова Use other Devices Использовать другие устройства Cancel Отмена Choose the option Выберите вариант Invaild response " Invaild response \ " AUTHENTICATION CANCELED АВТОРИЗАЦИЯ ОТМЕНА === BIOMETRIC DEVICES === === БИОМЕТРИЧЕСКИЕ УСТРОЙСТВА === Choose the device Выберите устройство Sevice Name Имя ячейки DISPLAY env DISPLAY env User пользователь Display debug information Отображать отладочную информацию Device short name Краткое название устройства BIOMETRIC AUTHENTICATION БИОМЕТРИЧЕСКАЯ АУТЕНТИФИКАЦИЯ Press Q or Esc to cancel Нажмите Q или Esc, чтобы отменить AUTHENTICATION SUCCESS УСПЕХ АУТЕНТИФИКАЦИИ AUTHENTICATION FAILED АВТОРИЗАЦИЯ НЕИСПРАВНО BIOMETRIC AUTHENTICATION END КОНТРОЛЬ БИОМЕТРИЧЕСКОЙ АВТОРИЗАЦИИ authentication will be canceld ukui-biometric-auth/bioauth-bin/i18n_ts/bo.ts0000644000175000017500000000773414064326115020040 0ustar fengfeng QObject Try it again Use other Devices Cancel Choose the option Invaild response " authentication will be canceld AUTHENTICATION CANCELED === BIOMETRIC DEVICES === Choose the device Sevice Name DISPLAY env User Display debug information Device short name BIOMETRIC AUTHENTICATION Press Q or Esc to cancel AUTHENTICATION SUCCESS AUTHENTICATION FAILED BIOMETRIC AUTHENTICATION END ukui-biometric-auth/bioauth-bin/i18n_ts/fr.ts0000644000175000017500000000645114064326115020042 0ustar fengfeng BioDevices FingerPrint Empreinte digitale FingerVein FingerVein Iris Iris Face Visage VoicePrint VoicePrint QObject Try it again Essayez à nouveau Use other Devices Utiliser d'autres appareils Cancel Annuler Choose the option Choisissez l'option Invaild response " Réponse Invaild \ " AUTHENTICATION CANCELED AUTHENTIFICATION ANNULEE === BIOMETRIC DEVICES === === DISPOSITIFS BIOMETRIQUES === Choose the device Choisissez l'appareil Sevice Name Nom de Sevice DISPLAY env AFFICHER env User Utilisateur Display debug information Afficher les informations de débogage Device short name Nom abrégé de l'appareil BIOMETRIC AUTHENTICATION AUTHENTIFICATION BIOMETRIQUE Press Q or Esc to cancel Appuyez sur Q ou Echap pour annuler AUTHENTICATION SUCCESS SUCCÈS D'AUTHENTIFICATION AUTHENTICATION FAILED AUTHENTIFICATION ÉCHOUÉE BIOMETRIC AUTHENTICATION END FIN DE L'AUTHENTIFICATION BIOMÉTRIQUE authentication will be canceld ukui-biometric-auth/bioauth/0000755000175000017500000000000014101710120015003 5ustar fengfengukui-biometric-auth/bioauth/CMakeLists.txt0000644000175000017500000000236214101710120017546 0ustar fengfengqt5_wrap_ui(BioAuthWidgets_SRC src/bioauthwidget.ui src/biodeviceswidget.ui ) qt5_wrap_cpp(BioAuth_SRC include/bioauth.h include/biodevices.h ) qt5_wrap_cpp(BioAuthWidgets_SRC include/bioauthwidget.h include/biodeviceswidget.h include/giodbus.h ) set(BioAuth_SRC ${BioAuth_SRC} src/bioauth.cpp src/biodevices.cpp src/biotypes.cpp ) set(BioAuthWidgets_SRC ${BioAuthWidgets_SRC} src/bioauthwidget.cpp src/biodeviceswidget.cpp src/giodbus.cpp ) include_directories( ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} include ../common ) add_library(BioAuth STATIC ${BioAuth_SRC}) target_link_libraries(BioAuth Qt5::Core Qt5::DBus) add_library(BioAuthWidgets STATIC ${BioAuthWidgets_SRC}) target_link_libraries(BioAuthWidgets BioAuth Qt5::Widgets ${OpenCV_LIBS} ${GIOUNIX2_LIBRARIES}) #add_library(BioAuth OBJECT ${BioAuth_SRC}) #add_library(BioAuthWidgets OBJECT ${BioAuth_SRC} ${BioAuthWidgets_SRC}) file(GLOB ts_files i18n_ts/*.ts) qt5_add_translation(qm_files ${ts_files}) add_custom_target(bioauth_i18n DEPENDS ${qm_files} SOURCES ${ts_files}) add_dependencies(BioAuth bioauth_i18n) install(FILES ${qm_files} DESTINATION ${UKUI_BIOMETRIC_DIR}/i18n_qm) ukui-biometric-auth/bioauth/src/0000755000175000017500000000000014107167520015612 5ustar fengfengukui-biometric-auth/bioauth/src/biodevices.cpp0000644000175000017500000002242214064326115020433 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "biodevices.h" #include #include #include #include #include #include "generic.h" BioDevices::BioDevices(QObject *parent) : QObject(parent), isShowHotPlug(false), useFirstDevice(false) { connectToService(); getDevicesList(); useFirstDevice = getUseFirstDevice(); } void BioDevices::connectToService() { qRegisterMetaType(); serviceInterface = new QDBusInterface(BIO_DBUS_SERVICE, BIO_DBUS_PATH, BIO_DBUS_INTERFACE, QDBusConnection::systemBus()); connect(serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)), this, SLOT(onUSBDeviceHotPlug(int,int,int))); serviceInterface->setTimeout(2147483647); } void BioDevices::onUSBDeviceHotPlug(int deviceId, int action, int devNumNow) { qDebug() << deviceId << action << devNumNow; QString text = ""; if(action == -1){ DeviceInfo *device = findDevice(deviceId); if(device) text = tr("Unplugging of %1 device detected").arg(bioTypeToString_tr(device->biotype)); } getDevicesList(); emit deviceCountChanged(deviceInfos.size()); if(action == 1){ DeviceInfo *device = findDevice(deviceId); if(device) text = tr("%1 device insertion detected").arg(bioTypeToString_tr(device->biotype)); } if(isShowHotPlug && text != ""){ QDBusInterface iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QList args; args<<(tr("biometric")) <<((unsigned int) 0) <<"" <call("GetDevList"); if(msg.type() == QDBusMessage::ErrorMessage){ LOG() << msg.errorMessage(); return; } /* 设备数量 */ int deviceNum = msg.arguments().at(0).toInt(); /* 读取设备详细信息,并存储到列表中 */ QDBusArgument argument = msg.arguments().at(1).value(); QList infos; argument >> infos; for(auto info : deviceInfos) delete info; deviceInfos.clear(); for(int i = 0; i < deviceNum; i++) { DeviceInfo *deviceInfo = new DeviceInfo; infos.at(i).value() >> *deviceInfo; if(deviceInfo->device_available > 0) //设备可用 deviceInfos.push_back(deviceInfo); } } int BioDevices::count() { return deviceInfos.size(); } int BioDevices::GetUserDevCount(int uid) { int count = 0; QDBusMessage msg = serviceInterface->call("GetDevList"); if(msg.type() == QDBusMessage::ErrorMessage){ LOG() << msg.errorMessage(); return 0; } int deviceNum = msg.arguments().at(0).toInt(); QDBusArgument argument = msg.arguments().at(1).value(); QList infos; argument >> infos; for(int i = 0; i < deviceNum; i++) { DeviceInfo *deviceInfo = new DeviceInfo; infos.at(i).value() >> *deviceInfo; if(deviceInfo->device_available > 0 && GetUserDevFeatureCount(uid,deviceInfo->device_id)>0) //设备可用 count++; } return count; } int BioDevices::GetUserDevFeatureCount(int uid,int drvid) { QDBusMessage FeatureResult = serviceInterface->call(QStringLiteral("GetFeatureList"),drvid,uid,0,-1); if(FeatureResult.type() == QDBusMessage::ErrorMessage) { qWarning() << "GetFeatureList error:" << FeatureResult.errorMessage(); return 0; } return FeatureResult.arguments().takeFirst().toInt(); } int BioDevices::getFeatureCount(int uid, int indexStart, int indexEnd) { int res = 0; for(int i = 0; i < deviceInfos.count(); i++) { DeviceInfo *deviceInfo = deviceInfos.at(i); QDBusReply reply = serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000)); QDBusMessage featurecount = serviceInterface->call("GetFeatureList",deviceInfo->device_id,uid,indexStart,indexEnd); if(featurecount.type() == QDBusMessage::ErrorMessage) { qWarning() << "GetFeatureList error:" << featurecount.errorMessage(); }else{ res += featurecount.arguments().takeFirst().toInt(); } } return res; } QMap> BioDevices::getAllDevices() { QMap> devices; for(auto deviceInfo : deviceInfos) { devices[deviceInfo->biotype].push_back(*deviceInfo); } return devices; } QMap> BioDevices::getUserDevices(int uid) { QMap> devices; for(auto deviceInfo : deviceInfos) { if(GetUserDevFeatureCount(uid,deviceInfo->device_id) > 0) devices[deviceInfo->biotype].push_back(*deviceInfo); } return devices; } QList BioDevices::getDevices(int type) { QList devices; for(auto deviceInfo : deviceInfos) { if (deviceInfo->biotype == type) devices.push_back(*deviceInfo); } return devices; } void BioDevices::setIsShowHotPlug(bool isShow) { isShowHotPlug = isShow; } bool BioDevices::getUseFirstDevice() { QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); return settings.value("UseFirstDevice").toBool(); } bool BioDevices::GetHiddenSwitchButton() { QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); if(sysSettings.contains("HiddenSwitchButton")) return sysSettings.value("HiddenSwitchButton").toBool(); else return false; } int BioDevices::getFailedTimes() { QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); if(sysSettings.contains("MaxFailedTimes")) return sysSettings.value("MaxFailedTimes").toInt(); else return 3; } DeviceInfo* BioDevices::getDefaultDevice(uid_t uid) { if(deviceInfos.size() <= 0) return nullptr; QString defaultDeviceName; struct passwd *pwd = getpwuid(uid); QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf"; QSettings userConfig(userConfigFile, QSettings::IniFormat); qDebug() << userConfig.fileName(); defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString(); qDebug() << defaultDeviceName; if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)) { QSettings sysConfig(GET_STR(CONFIG_FILE), QSettings::IniFormat); defaultDeviceName = sysConfig.value(DEFAULT_DEVICE).toString(); } if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)){ QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf"; QSettings userConfig(userConfigFile, QSettings::IniFormat); defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString(); } qDebug() << "default device: " << defaultDeviceName; if(defaultDeviceName.isEmpty()){ if(!useFirstDevice) return nullptr; else return getFirstDevice(); } return findDevice(defaultDeviceName); } DeviceInfo* BioDevices::findDevice(const int id) { for(auto deviceInfo : deviceInfos) { if(deviceInfo->device_id == id) return deviceInfo; } //qDebug() << deviceName << "doesn't exists"; return nullptr; } DeviceInfo* BioDevices::findDevice(const QString &deviceName) { for(auto deviceInfo : deviceInfos) { if(deviceInfo->device_shortname == deviceName) return deviceInfo; } qDebug() << deviceName << "doesn't exists"; return nullptr; } DeviceInfo* BioDevices::getFirstDevice() { if(!deviceInfos.isEmpty()) return deviceInfos.at(0); return nullptr; } QString BioDevices::bioTypeToString_tr(int type) { switch(type) { case BIOTYPE_FINGERPRINT: return tr("FingerPrint"); case BIOTYPE_FINGERVEIN: return tr("FingerVein"); case BIOTYPE_IRIS: return tr("Iris"); case BIOTYPE_FACE: return tr("Face"); case BIOTYPE_VOICEPRINT: return tr("VoicePrint"); } return QString(); } ukui-biometric-auth/bioauth/src/bioauthwidget.ui0000644000175000017500000001142514107167520021013 0ustar fengfeng BioAuthWidget 0 0 404 376 Form Qt::Horizontal 40 20 130 130 130 130 Qt::AlignCenter Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 100 Qt::AlignCenter Qt::AlignCenter true Qt::Vertical QSizePolicy::MinimumExpanding 20 30 50 16777215 PointingHandCursor More 50 16777215 PointingHandCursor Retry 80 16777215 PointingHandCursor Password ukui-biometric-auth/bioauth/src/bioauthwidget.cpp0000644000175000017500000001126714107167520021164 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "bioauthwidget.h" #include "ui_bioauthwidget.h" #include #include "generic.h" #include #include #include "giodbus.h" #include #include #include #include BioAuthWidget::BioAuthWidget(QWidget *parent) : QWidget(parent), ui(new Ui::BioAuthWidget), bioAuth(nullptr) { ui->setupUi(this); ui->btnRetry->setVisible(false); ui->btnMore->setVisible(false); } BioAuthWidget::~BioAuthWidget() { delete ui; } void BioAuthWidget::emitSwithToPassword() { Q_EMIT switchToPassword(); } void BioAuthWidget::on_btnPasswdAuth_clicked() { stopAuth(); //Q_EMIT switchToPassword(); QTimer::singleShot(100,this,SLOT(emitSwithToPassword())); } void BioAuthWidget::on_btnMore_clicked() { Q_EMIT selectDevice(); } void BioAuthWidget::on_btnRetry_clicked() { if(bioAuth && !bioAuth->isAuthenticating()) { setMovie(); bioAuth->startAuth(); } } void BioAuthWidget::onBioAuthNotify(const QString ¬ifyMsg) { ui->lblBioNotify->setText(notifyMsg); } void BioAuthWidget::onBioAuthComplete(uid_t uid, bool ret) { setImage(); dup_fd = -1; Q_EMIT authComplete(uid, ret); } void BioAuthWidget::setMovie() { if(device.biotype == BIOTYPE_FACE) return ; QString typeString = bioTypeToString(device.biotype); QString moviePath = QString("%1/images/%2.gif").arg(GET_STR(UKUI_BIOMETRIC)).arg(typeString); QMovie *movie = new QMovie(moviePath); movie->setScaledSize(QSize(ui->lblBioImage->width(), ui->lblBioImage->height())); ui->lblBioImage->setMovie(movie); movie->start(); ui->btnRetry->setVisible(false); qDebug() << "set movie " << moviePath; } void BioAuthWidget::setImage() { if(device.biotype == BIOTYPE_FACE) return ; QString typeString = bioTypeToString(device.biotype); QString pixmapPath = QString("%1/images/%2.png").arg(GET_STR(UKUI_BIOMETRIC)).arg(typeString); QPixmap pixmap(pixmapPath); pixmap = pixmap.scaled(ui->lblBioImage->width(), ui->lblBioImage->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); ui->lblBioImage->setPixmap(pixmap); ui->btnRetry->setVisible(true); qDebug() << "set pixmap " << typeString; } void BioAuthWidget::onFrameWritten(int deviceId) { if(dup_fd == -1){ dup_fd = get_server_gvariant_stdout(deviceId); } cv::Mat img; lseek(dup_fd, 0, SEEK_SET); char base64_bufferData[1024*1024]; int rc = read(dup_fd, base64_bufferData, 1024*1024); printf("rc = %d\n", rc); cv::Mat mat2(1, sizeof(base64_bufferData), CV_8U, base64_bufferData); img = cv::imdecode(mat2, cv::IMREAD_COLOR); QImage srcQImage = QImage((uchar*)(img.data), img.cols, img.rows, QImage::Format_RGB888); ui->lblBioImage->setPixmap(QPixmap::fromImage(srcQImage).scaled(ui->lblBioImage->size())); ui->btnRetry->setVisible(false); } void BioAuthWidget::hidePasswdButton() { ui->btnPasswdAuth->hide(); } bool BioAuthWidget::isAuthenticating() { if(bioAuth){ return bioAuth->isAuthenticating(); } return false; } void BioAuthWidget::stopAuth() { if(bioAuth){ bioAuth->stopAuth(); } } void BioAuthWidget::startAuth(uid_t uid, const DeviceInfo &device) { this->uid = uid; this->device = device; ui->lblBioDevice->setText(tr("Current Device: ") + device.device_shortname); if(bioAuth) { bioAuth->stopAuth(); delete bioAuth; bioAuth = nullptr; } setMovie(); bioAuth = new BioAuth(uid, device, this); connect(bioAuth, &BioAuth::notify, this, &BioAuthWidget::onBioAuthNotify); connect(bioAuth, &BioAuth::authComplete, this, &BioAuthWidget::onBioAuthComplete); connect(bioAuth, &BioAuth::frameWritten,this,&BioAuthWidget::onFrameWritten); dup_fd = -1; fd = -1; bioAuth->startAuth(); } void BioAuthWidget::setMoreDevices(bool hasMore) { ui->btnMore->setVisible(hasMore); } ukui-biometric-auth/bioauth/src/biodeviceswidget.cpp0000644000175000017500000000610714064326115021641 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "biodeviceswidget.h" #include "ui_biodeviceswidget.h" BioDevicesWidget::BioDevicesWidget(QWidget *parent) : QWidget(parent), ui(new Ui::BioDevicesWidget) { ui->setupUi(this); connect(&bioDevices, &BioDevices::deviceCountChanged, this, &BioDevicesWidget::onDeviceCountChanged); } BioDevicesWidget::~BioDevicesWidget() { delete ui; } void BioDevicesWidget::init(uid_t uid) { this->uid = uid; devicesMap = bioDevices.getUserDevices(uid); ui->cmbDeviceTypes->clear(); for(auto i : devicesMap.keys()) { ui->cmbDeviceTypes->addItem(BioDevices::bioTypeToString_tr(i), i); } /* set the default device as current device */ DeviceInfo *device = bioDevices.getDefaultDevice(uid); if(device) { int index = ui->cmbDeviceTypes->findData(device->biotype); QList &deviceList = devicesMap[index]; auto iter = std::find_if(deviceList.constBegin(), deviceList.constEnd(), [&](const DeviceInfo &deviceInfo){ return deviceInfo.device_shortname == device->device_shortname; }); int row = iter - deviceList.constBegin(); ui->cmbDeviceTypes->setCurrentIndex(index); ui->lwDevices->setCurrentRow(row); } Q_EMIT deviceCountChanged(bioDevices.count()); } void BioDevicesWidget::on_btnBack_clicked() { Q_EMIT back(); } void BioDevicesWidget::on_btnOK_clicked() { int row = ui->lwDevices->currentRow(); int type = ui->cmbDeviceTypes->itemData(ui->cmbDeviceTypes->currentIndex()).toInt(); Q_EMIT deviceChanged(devicesMap[type].at(row)); } void BioDevicesWidget::on_lwDevices_doubleClicked(const QModelIndex &) { on_btnOK_clicked(); } void BioDevicesWidget::on_cmbDeviceTypes_currentIndexChanged(int index) { qDebug() << "type changed"; ui->lwDevices->clear(); int i = ui->cmbDeviceTypes->itemData(index).toInt(); for(auto device : devicesMap[i]) ui->lwDevices->addItem(device.device_shortname); if(ui->lwDevices->currentRow()<0) ui->lwDevices->setCurrentRow(0); } void BioDevicesWidget::onDeviceCountChanged() { int type = ui->cmbDeviceTypes->itemData(ui->cmbDeviceTypes->currentIndex()).toInt(); init(uid); int index = ui->cmbDeviceTypes->findData(type); ui->cmbDeviceTypes->setCurrentIndex(index >= 0 ? index : 0); Q_EMIT deviceCountChanged(bioDevices.count()); } ukui-biometric-auth/bioauth/src/bioauth.cpp0000644000175000017500000000735714101710120017745 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "bioauth.h" #include BioAuth::BioAuth(qint32 uid, const DeviceInfo &deviceInfo, QObject *parent) : QObject(parent), uid(uid), deviceInfo(deviceInfo), isInAuthentication(false) { serviceInterface = new QDBusInterface(BIO_DBUS_SERVICE, BIO_DBUS_PATH, BIO_DBUS_INTERFACE, QDBusConnection::systemBus()); connect(serviceInterface, SIGNAL(StatusChanged(int, int)), this, SLOT(onStatusChanged(int,int))); connect(serviceInterface, SIGNAL(FrameWritten(int)), this, SLOT(onFrameWritten(int))); serviceInterface->setTimeout(2147483647); } BioAuth::~BioAuth() { // stopAuth(); } void BioAuth::setDevice(const DeviceInfo &deviceInfo) { this->deviceInfo = deviceInfo; } void BioAuth::startAuth() { // stopAuth(); /* 开始认证识别 */ LOG() << "start biometric verification"; QList args; args << QVariant(deviceInfo.device_id) << QVariant(uid) << QVariant(0) << QVariant(-1); isInAuthentication = true; QDBusPendingCall call = serviceInterface->asyncCallWithArgumentList("Identify", args); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, &BioAuth::onIdentityComplete); } void BioAuth::stopAuth() { if(!isInAuthentication) return ; QDBusReply reply = serviceInterface->call("StopOps", QVariant(deviceInfo.device_id), QVariant(3000)); if(!reply.isValid()) qWarning() << "StopOps error: " << reply.error(); isInAuthentication = false; } bool BioAuth::isAuthenticating() { return isInAuthentication; } void BioAuth::onIdentityComplete(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if(reply.isError()){ isInAuthentication = false; LOG() << reply.error(); Q_EMIT authComplete(-1, false); return; } qint32 result = reply.argumentAt(0).toInt(); qint32 retUid = reply.argumentAt(1).toInt(); LOG() << "Identify complete: " << result << " " << retUid; /* 识别生物特征成功,发送认证结果 */ if(isInAuthentication){ isInAuthentication = false; if(result == DBUS_RESULT_SUCCESS && retUid == uid) Q_EMIT authComplete(retUid, true); else Q_EMIT authComplete(retUid, false); } } void BioAuth::onFrameWritten(int deviceId) { Q_EMIT frameWritten(deviceId); } void BioAuth::onStatusChanged(int deviceId, int statusType) { if(statusType != STATUS_NOTIFY) return; LOG() << "status changed " << deviceId << " " << statusType; QDBusMessage msg = serviceInterface->call("GetNotifyMesg", QVariant(deviceId)); if(msg.type() == QDBusMessage::ErrorMessage){ LOG() << msg.errorMessage(); return; } QString message = msg.arguments().at(0).toString(); LOG() << message; Q_EMIT notify(message); } ukui-biometric-auth/bioauth/src/biotypes.cpp0000644000175000017500000000520614064326115020156 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "biotypes.h" #include QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo) { argument.beginStructure(); argument << deviceInfo.device_id << deviceInfo.device_shortname << deviceInfo.device_fullname << deviceInfo.driver_enable << deviceInfo.device_available << deviceInfo.biotype << deviceInfo.stotype << deviceInfo.eigtype << deviceInfo.vertype << deviceInfo.idtype << deviceInfo.bustype << deviceInfo.dev_status << deviceInfo.ops_status; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo) { argument.beginStructure(); argument >> deviceInfo.device_id >> deviceInfo.device_shortname >> deviceInfo.device_fullname >> deviceInfo.driver_enable >> deviceInfo.device_available >> deviceInfo.biotype >> deviceInfo.stotype >> deviceInfo.eigtype >> deviceInfo.vertype >> deviceInfo.idtype >> deviceInfo.bustype >> deviceInfo.dev_status >> deviceInfo.ops_status; argument.endStructure(); return argument; } bool DeviceInfo::operator==(const DeviceInfo& deviceInfo) const { if(this->device_shortname == deviceInfo.device_shortname && this->device_available == deviceInfo.device_available) return true; return false; } QDebug& operator<<(QDebug &stream, const DeviceInfo &deviceInfo) { stream << deviceInfo.device_id << deviceInfo.device_shortname << deviceInfo.biotype << deviceInfo.device_available; return stream; } QString bioTypeToString(int type) { switch(type) { case BIOTYPE_FINGERPRINT: return ("FingerPrint"); case BIOTYPE_FINGERVEIN: return ("FingerVein"); case BIOTYPE_IRIS: return ("Iris"); case BIOTYPE_FACE: return ("Face"); case BIOTYPE_VOICEPRINT: return ("VoicePrint"); } return QString(); } ukui-biometric-auth/bioauth/src/biodeviceswidget.ui0000644000175000017500000000670014064326115021473 0ustar fengfeng BioDevicesWidget 0 0 400 300 Form Device types: 0 0 0 70 Qt::Horizontal 40 20 50 0 50 16777215 PointingHandCursor Back Qt::Horizontal QSizePolicy::Minimum 10 20 50 0 50 16777215 PointingHandCursor OK ukui-biometric-auth/bioauth/src/giodbus.cpp0000644000175000017500000000417314101710120017737 0ustar fengfeng#include "giodbus.h" #include #include #include int get_server_gvariant_stdout (int drvid) { GDBusMessage *method_call_message; GDBusMessage *method_reply_message; GUnixFDList *fd_list; GError **error = NULL; gint fd,dup_fd; const gchar * response; fd = -1; dup_fd = -1; method_call_message = NULL; method_reply_message = NULL; GDBusConnection *con = g_bus_get_sync(G_BUS_TYPE_SYSTEM,NULL,NULL); method_call_message = g_dbus_message_new_method_call ("org.ukui.Biometric", "/org/ukui/Biometric", "org.ukui.Biometric", "GetFrameFd"); g_dbus_message_set_body (method_call_message, g_variant_new ("(i)", drvid)); method_reply_message = g_dbus_connection_send_message_with_reply_sync (con, method_call_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, /* out_serial */ NULL, /* cancellable */ error); if (method_reply_message == NULL) goto out; if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { g_dbus_message_to_gerror (method_reply_message, error); goto out; } g_print("%s",g_dbus_message_print(method_reply_message,0)); fd_list = g_dbus_message_get_unix_fd_list(method_reply_message); fd = g_unix_fd_list_get(fd_list,0,error); g_print("get fd : %d\n", fd); dup_fd = dup(fd); g_print("dup fd : %d\n", dup_fd); out: g_object_unref (method_call_message); g_object_unref (method_reply_message); return fd; } ukui-biometric-auth/bioauth/i18n_ts/0000755000175000017500000000000014064326115016307 5ustar fengfengukui-biometric-auth/bioauth/i18n_ts/es.ts0000644000175000017500000000434514064326115017274 0ustar fengfeng BioAuthWidget Form Formar TextLabel TextLabel More Más Retry Procesar de nuevo Password Contraseña Current Device: BioDevices FingerPrint Huella dactilar FingerVein FingerVein Iris Iris Face Cara VoicePrint Impresión de voz Unplugging of %1 device detected %1 device insertion detected biometric BioDevicesWidget Form Formar Device types: Tipos de dispositivos: Back Espalda OK DE ACUERDO ukui-biometric-auth/bioauth/i18n_ts/pt.ts0000644000175000017500000000433214064326115017304 0ustar fengfeng BioAuthWidget Form Formato TextLabel TextLabel More Mais Retry Tente novamente Password Senha Current Device: BioDevices FingerPrint Impressão digital FingerVein FingerVein Iris Íris Face Cara VoicePrint VoicePrint Unplugging of %1 device detected %1 device insertion detected biometric BioDevicesWidget Form Formato Device types: Tipos de dispositivos: Back Costas OK Está bem ukui-biometric-auth/bioauth/i18n_ts/zh_CN.ts0000644000175000017500000001041514064326115017661 0ustar fengfeng BioAuthWidget Form TextLabel More 更多 Retry 重试 Password 密码 Current Device: 当前设备: BioDevices Unplugging of %1 device detected 检测到%1设备拔出 %1 device insertion detected 检测到%1设备插入 biometric 生物特征 FingerPrint 指纹 FingerVein 指静脉 Iris 虹膜 Face 人脸 VoicePrint 声纹 BioDevicesWidget Form Device types: 设备类型: Back 返回 OK 确定 FingerPrint 指纹 QObject FingerPrint 指纹 FingerVein 指静脉 Iris 虹膜 Face 人脸 VoicePrint 声纹 ukui-biometric-auth/bioauth/i18n_ts/tr.ts0000644000175000017500000001043514064326115017307 0ustar fengfeng BioAuthWidget Form TextLabel More Daha Fazla Retry Yeniden Dene Password Parola Current Device: Şuanki Aygıt: BioDevices Unplugging of %1 device detected %1 device insertion detected biometric FingerPrint Parmak İzi FingerVein Damar İzi Iris Göz Face Yüz VoicePrint Ses İzi BioDevicesWidget Form Device types: Aygıt türü: Back Geri OK Tamam FingerPrint Parmak İzi QObject FingerPrint Parmak İzi FingerVein Damar İzi Iris Göz Face Yüz VoicePrint Ses İzi ukui-biometric-auth/bioauth/i18n_ts/ru.ts0000644000175000017500000000435214064326115017311 0ustar fengfeng BioAuthWidget Form форма TextLabel TextLabel More Больше Retry Retry Password пароль Current Device: BioDevices FingerPrint FingerPrint FingerVein FingerVein Iris Ирис Face Лицо VoicePrint Voiceprint Unplugging of %1 device detected %1 device insertion detected biometric BioDevicesWidget Form форма Device types: Типы устройств: Back назад OK ОК ukui-biometric-auth/bioauth/i18n_ts/bo.ts0000644000175000017500000000724014064326115017262 0ustar fengfeng BioAuthWidget Form TextLabel More Retry Password Current Device: BioDevices Unplugging of %1 device detected %1 device insertion detected biometric FingerPrint FingerVein Iris Face VoicePrint BioDevicesWidget Form Device types: Back OK ukui-biometric-auth/bioauth/i18n_ts/fr.ts0000644000175000017500000000434114064326115017270 0ustar fengfeng BioAuthWidget Form Forme TextLabel TextLabel More Plus Retry Recommencez Password Mot de passe Current Device: BioDevices FingerPrint Empreinte digitale FingerVein FingerVein Iris Iris Face Visage VoicePrint VoicePrint Unplugging of %1 device detected %1 device insertion detected biometric BioDevicesWidget Form Forme Device types: Types d'appareils: Back Arrière OK D'accord ukui-biometric-auth/bioauth/include/0000755000175000017500000000000014101710120016426 5ustar fengfengukui-biometric-auth/bioauth/include/bioauthwidget.h0000644000175000017500000000336114101710120021441 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIOAUTHWIDGET_H #define BIOAUTHWIDGET_H #include #include "bioauth.h" namespace Ui { class BioAuthWidget; } class BioAuthWidget : public QWidget { Q_OBJECT public: explicit BioAuthWidget(QWidget *parent = 0); ~BioAuthWidget(); void hidePasswdButton(); bool isAuthenticating(); public slots: void startAuth(uid_t uid, const DeviceInfo &device); void setMoreDevices(bool hasMore); void stopAuth(); void emitSwithToPassword(); signals: void switchToPassword(); void selectDevice(); void authComplete(uid_t uid, bool ret); private slots: void on_btnPasswdAuth_clicked(); void on_btnMore_clicked(); void on_btnRetry_clicked(); void onBioAuthNotify(const QString ¬ifyMsg); void onBioAuthComplete(uid_t uid, bool ret); void onFrameWritten(int deviceId); private: void setMovie(); void setImage(); private: Ui::BioAuthWidget *ui; BioAuth *bioAuth; uid_t uid; DeviceInfo device; int fd = -1; int dup_fd = -1; }; #endif // BIOAUTHWIDGET_H ukui-biometric-auth/bioauth/include/bioauth.h0000644000175000017500000000331714101710120020236 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIOAUTH_H #define BIOAUTH_H #include #include "biotypes.h" class QDBusInterface; /*! * \brief The BioAuth class * 负责真正的生物识别操作,通过startAuth开始认证, * 认证完成后会发出携带结果的authComplete信号 */ class BioAuth : public QObject { Q_OBJECT public: explicit BioAuth(qint32 uid, const DeviceInfo &deviceInfo, QObject *parent = nullptr); ~BioAuth(); void setDevice(const DeviceInfo& deviceInfo); void startAuth(); void stopAuth(); bool isAuthenticating(); signals: void authComplete(uid_t uid, bool result); void notify(const QString &message); void frameWritten(int deviceId); private slots: void onIdentityComplete(QDBusPendingCallWatcher *watcher); void onStatusChanged(int deviceId, int statusType); void onFrameWritten(int drvid); private: QDBusInterface *serviceInterface; qint32 uid; DeviceInfo deviceInfo; bool isInAuthentication; }; #endif // BIOAUTH_H ukui-biometric-auth/bioauth/include/giodbus.h0000644000175000017500000000013014101710120020225 0ustar fengfeng#ifndef GIODBUS_H #define GIODBUS_H int get_server_gvariant_stdout(int drvid); #endif ukui-biometric-auth/bioauth/include/biometric.h0000644000175000017500000000155714064326115020603 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIOMETRIC_H #define BIOMETRIC_H #include "bioauth.h" #include "biodevices.h" #include "bioauthwidget.h" #include "biodeviceswidget.h" #endif // BIOMETRIC_H ukui-biometric-auth/bioauth/include/biotypes.h0000644000175000017500000000500614064326115020455 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIOCUSTOMTYPE_H #define BIOCUSTOMTYPE_H #include #include #define BIO_DBUS_SERVICE "org.ukui.Biometric" #define BIO_DBUS_PATH "/org/ukui/Biometric" #define BIO_DBUS_INTERFACE "org.ukui.Biometric" #define DEFAULT_DEVICE "DefaultDevice" #ifdef LOG #undef LOG #endif #define LOG() qDebug() << "[BIOMETRIC]" /* the type of device */ enum BioType { BIOTYPE_FINGERPRINT, BIOTYPE_FINGERVEIN, BIOTYPE_IRIS, BIOTYPE_FACE, BIOTYPE_VOICEPRINT, __MAX_NR_BIOTYPES }; /* StatusChanged D-Bus 信号触发时的状态变化类型 */ enum StatusType { STATUS_DEVICE, STATUS_OPERATION, STATUS_NOTIFY }; /* 录入/删除/搜索等 D-Bus 调用的最终结果,即返回值里的 result */ enum DBusResult { DBUS_RESULT_SUCCESS = 0, DBUS_RESULT_ERROR, DBUS_RESULT_DEVICEBUSY, DBUS_RESULT_NOSUCHDEVICE, DBUS_RESULT_PERMISSIONDENIED }; /* the info of device */ struct DeviceInfo { int device_id; QString device_shortname; /* aka driverName */ QString device_fullname; int driver_enable; /* The corresponding driver is enabled/disabled */ int device_available; /* The driver is enabled and the device is connected */ int biotype; int stotype; int eigtype; int vertype; int idtype; int bustype; int dev_status; int ops_status; bool operator==(const DeviceInfo&) const; bool operator !=(const DeviceInfo &deviceInfo) const { return !(*this == deviceInfo); } friend QDebug& operator<<(QDebug &stream, const DeviceInfo &deviceInfo); }; Q_DECLARE_METATYPE(DeviceInfo) QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo); const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo); QString bioTypeToString(int type); #endif // BIOCUSTOMTYPE_H ukui-biometric-auth/bioauth/include/biodeviceswidget.h0000644000175000017500000000276614064326115022151 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIODEVICESWIDGET_H #define BIODEVICESWIDGET_H #include #include "biodevices.h" namespace Ui { class BioDevicesWidget; } class BioDevicesWidget : public QWidget { Q_OBJECT public: explicit BioDevicesWidget(QWidget *parent = 0); ~BioDevicesWidget(); void init(uid_t uid); signals: void back(); void deviceChanged(const DeviceInfo &device); void deviceCountChanged(int count); private slots: void on_btnBack_clicked(); void on_btnOK_clicked(); void on_lwDevices_doubleClicked(const QModelIndex &); void on_cmbDeviceTypes_currentIndexChanged(int index); void onDeviceCountChanged(); private: Ui::BioDevicesWidget *ui; BioDevices bioDevices; QMap> devicesMap; uid_t uid; }; #endif // BIODEVICESWIDGET_H ukui-biometric-auth/bioauth/include/biodevices.h0000644000175000017500000000435014064326115020734 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef BIODEVICES_H #define BIODEVICES_H #include #include #include #include "biotypes.h" class QDBusInterface; /*! * \brief The BioDevices class * this class saves the list of all device information * and list of available devices' info list for each uid */ class BioDevices : public QObject { Q_OBJECT public: explicit BioDevices(QObject *parent = nullptr); int count(); QMap> getAllDevices(); QMap> getUserDevices(int uid); QList getDevices(int type); DeviceInfo* getDefaultDevice(uid_t uid); DeviceInfo* findDevice(const QString &deviceName); DeviceInfo* findDevice(const int id); DeviceInfo* getFirstDevice(); int getFeatureCount(int uid, int indexStart = 0, int indexEnd = -1); static QString bioTypeToString_tr(int type); void setIsShowHotPlug(bool isShow); int GetUserDevFeatureCount(int uid,int drvid); int GetUserDevCount(int uid); bool getUseFirstDevice(); int getFailedTimes(); bool GetHiddenSwitchButton(); private: void connectToService(); void getDevicesList(); signals: void deviceCountChanged(int newNum); private slots: void onUSBDeviceHotPlug(int deviceId, int action, int devNumNow); private: QDBusInterface *serviceInterface; QList deviceInfos; //the list of al device info bool isShowHotPlug; bool useFirstDevice; }; #endif // BIODEVICES_H ukui-biometric-auth/.gitattributes0000644000175000017500000000012514101720251016247 0ustar fengfengdebian/changelog merge=ours debian/compat merge=ours debian/source/format merge=ours ukui-biometric-auth/polkit-agent/0000755000175000017500000000000014107167520015766 5ustar fengfengukui-biometric-auth/polkit-agent/CMakeLists.txt0000644000175000017500000000271614107167520020534 0ustar fengfengcmake_minimum_required(VERSION 2.6) project(ukui-polkit-agent) find_package(PolkitQt5-1 REQUIRED 0.103.0) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) set(LIB_ARCH_PATH /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}) configure_file( ${PROJECT_SOURCE_DIR}/data/polkit-ukui-authentication-agent-1.desktop.in ${PROJECT_BINARY_DIR}/data/polkit-ukui-authentication-agent-1.desktop ) include_directories( ${POLKITQT-1_INCLUDE_DIR} ../common ../bioauth/include ) qt5_add_resources(polkit_SRCS assets.qrc) set(polkit_SRCS ${polkit_SRCS} src/PolkitAgent.cpp src/mainwindow.cpp src/PolkitListener.cpp src/sessionmanager.cpp src/users.cpp ../common/generic.cpp ) add_executable(polkit-ukui-authentication-agent-1 ${polkit_SRCS}) target_link_libraries(polkit-ukui-authentication-agent-1 Qt5::Core Qt5::Widgets Qt5::DBus ${POLKITQT-1_LIBRARIES} BioAuthWidgets ) install(TARGETS polkit-ukui-authentication-agent-1 DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-polkit) # 翻译文件 file(GLOB ts_files i18n_ts/*.ts) qt5_add_translation(qm_files ${ts_files}) add_custom_target(polkit_i18n DEPENDS ${qm_files} SOURCES ${ts_files}) add_dependencies(polkit-ukui-authentication-agent-1 polkit_i18n) install(FILES ${qm_files} DESTINATION ${UKUI_BIOMETRIC_DIR}/i18n_qm/polkit) install(FILES ${PROJECT_BINARY_DIR}/data/polkit-ukui-authentication-agent-1.desktop DESTINATION /etc/xdg/autostart) ukui-biometric-auth/polkit-agent/assets/0000755000175000017500000000000014107167520017270 5ustar fengfengukui-biometric-auth/polkit-agent/assets/arrow_right.svg0000644000175000017500000000124614064326115022342 0ustar fengfengukui-biometric-auth/polkit-agent/assets/arrow_down.svg0000644000175000017500000000146414064326115022176 0ustar fengfengukui-biometric-auth/polkit-agent/assets.qrc0000644000175000017500000000034614107167520020002 0ustar fengfeng assets/arrow_down.svg assets/arrow_right.svg src/main.qss ukui-biometric-auth/polkit-agent/data/0000755000175000017500000000000014064326115016676 5ustar fengfengukui-biometric-auth/polkit-agent/data/polkit-ukui-authentication-agent-1.desktop.in0000644000175000017500000000772314064326115027433 0ustar fengfeng[Desktop Entry] Name=PolicyKit Authentication Agent Name[ca]=Agent d'autenticació del PolicyKit Name[ca@valencia]=Agent d'autenticació del PolicyKit Name[cs]=Ověřovací agent PolicyKitu Name[da]=PolicyKit autentificeringsagent Name[de]=PolicyKit-Authentifizierungs-Agent Name[el]=Πράκτορας ταυτοποίησης PolicyKit Name[en_GB]=PolicyKit Authentication Agent Name[es]=Agente de autenticación de PolicyKit Name[et]=PolicyKiti autentimisagent Name[eu]=PolicyKit autentifikazio agentea Name[fi]=PolicyKit-tunnistautumisagentti Name[fr]=Agent d'authentification de « PolicyKit » Name[gl]=Axente de autenticación de PolicyKit Name[hu]=PolicyKit hitelesítési ügynök Name[id]=PolicyKit Authentication Agent Name[it]=Agente di autenticazione di PolicyKit Name[ko]=PolicyKit 인증 에이전트 Name[nl]=Authenticatieagent van PolicyKit Name[nn]=PolicyKit-autentiseringsagent Name[pa]=ਪਾਲਸੀਕਿਟ ਪਰਮਾਣਕਿਤਾ ਏਜੰਟ Name[pl]=Usługa uwierzytelnienia PolicyKit Name[pt]=Agente de Autenticação do PolicyKit Name[pt_BR]=Agente de Autenticação do PolicyKit Name[ru]=Агент аутентификации PolicyKit Name[sk]=Overovací dialóg PolicyKit Name[sl]=Overitveni posrednik PolicyKit Name[sr]=Полисикитов агент за аутентификовање Name[sr@ijekavian]=Полисикитов агент за аутентификовање Name[sr@ijekavianlatin]=PolicyKitov agent za autentifikovanje Name[sr@latin]=PolicyKitov agent za autentifikovanje Name[sv]=Policykit behörighetsmodul Name[tr]=PolicyKit Kimlik Doğrulama Aracı Name[uk]=Агент розпізнавання PolicyKit Name[x-test]=xxPolicyKit Authentication Agentxx Name[zh_CN]=PolicyKit 认证代理 Name[zh_TW]=PolicyKit 認證代理程式 Comment=PolicyKit Authentication Agent Comment[ca]=Agent d'autenticació del PolicyKit Comment[ca@valencia]=Agent d'autenticació del PolicyKit Comment[cs]=Ověřovací agent PolicyKitu Comment[da]=PolicyKit autentificeringsagent Comment[de]=PolicyKit-Authentifizierungs-Agent Comment[el]=Πράκτορας ταυτοποίησης PolicyKit Comment[en_GB]=PolicyKit Authentication Agent Comment[es]=Agente de autenticación de PolicyKit Comment[et]=PolicyKiti autentimisagent Comment[eu]=PolicyKit autentifikazio agentea Comment[fi]=PolicyKit-tunnistautumisagentti Comment[fr]=Agent d'authentification de « PolicyKit » Comment[gl]=Axente de autenticación de PolicyKit Comment[hu]=PolicyKit hitelesítési ügynök Comment[id]=Agen Kewenangan PolicyKit Comment[it]=Agente di autenticazione di PolicyKit Comment[ko]=PolicyKit 인증 에이전트 Comment[nl]=Authenticatieagent van PolicyKit Comment[nn]=PolicyKit-autentiseringsagent Comment[pa]=ਪਾਲਸੀਕਿਟ ਪਰਮਾਣਕਿਤਾ ਏਜੰਟ Comment[pl]=Usługa uwierzytelnienia PolicyKit Comment[pt]=Agente de Autenticação do PolicyKit Comment[pt_BR]=Agente de Autenticação do PolicyKit Comment[ru]=Агент аутентификации PolicyKit Comment[sk]=Overovací dialóg PolicyKit Comment[sl]=Overitveni posrednik PolicyKit Comment[sr]=Полисикитов агент за аутентификовање Comment[sr@ijekavian]=Полисикитов агент за аутентификовање Comment[sr@ijekavianlatin]=PolicyKitov agent za autentifikovanje Comment[sr@latin]=PolicyKitov agent za autentifikovanje Comment[sv]=Policykit behörighetsmodul Comment[tr]=PolicyKit Kimlik Doğrulama Aracı Comment[uk]=Агент розпізнавання PolicyKit Comment[x-test]=xxPolicyKit Authentication Agentxx Comment[zh_CN]=PolicyKit 认证代理 Comment[zh_TW]=PolicyKit 認證代理程式 Exec=${LIB_ARCH_PATH}/ukui-polkit/polkit-ukui-authentication-agent-1 Icon=ukui-polkit Terminal=false Type=Application Categories= OnlyShowIn=UKUI;MATE X-UKUI-StartupNotify=false X-UKUI-AutoRestart=true X-UKUI-Autostart-Phase=Application NoDisplay=true X-DBUS-StartupType=Unique X-MATE-Autostart-Phase=Initialization X-MATE-StartupNotify=false X-MATE-AutoRestart=true ukui-biometric-auth/polkit-agent/src/0000755000175000017500000000000014107167520016555 5ustar fengfengukui-biometric-auth/polkit-agent/src/mainwindow.ui0000644000175000017500000003406414107167520021277 0ustar fengfeng MainWindow 0 0 380 581 0 0 380 0 Form QLayout::SetDefaultConstraint 64 64 96 96 12 75 true true true 0 120 0 0 0 30 Qt::NoContextMenu 0 30 16777215 30 Qt::AlignCenter true 0 Qt::Horizontal 40 20 PointingHandCursor Biometric Qt::Horizontal 40 20 0 PointingHandCursor Qt::NoFocus Details Qt::Horizontal 40 20 0 0 0 200 16777215 200 0 5 QLayout::SetDefaultConstraint 0 6 0 0 true Vendor: true Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 true false 0 0 true false 0 0 true false Description: true Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Polkit.caller-pid: true Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 true 0 0 Action: true Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Polkit.subject-pid: true Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 Qt::Horizontal 40 20 0 0 PointingHandCursor Cancel 0 0 PointingHandCursor Authenticate ukui-biometric-auth/polkit-agent/src/main.qss0000644000175000017500000000024114107167520020226 0ustar fengfeng#btnCancel, #btnAuth { min-height: 24px; min-width: 80px; } #btnDetails { icon-size: 14px; } #lwDevices { } #lwDevices::item { height: 30px; } ukui-biometric-auth/polkit-agent/src/users.cpp0000644000175000017500000001201114064326115020414 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "users.h" #include #include #include #include #include #include "types.h" #include #include QDebug operator<<(QDebug stream, const UserItem &user) { stream << user.name << user.realName << user.uid << user.icon << user.path; return stream; } Users::Users(QObject *parent) : QObject(parent) { defaultIcon = ":/image/assets/iconFace.png"; loadUsers(); } QList Users::getUsers() { return users; } UserItem Users::getUserByName(const QString &name) { for(int i = 0 ; i < users.size() ; i++) { if(users.at(i).name == name) { return users.at(i); } } UserItem user; if(name == "root") { user.icon = "/root/.face"; if(!QFile(user.icon).exists()) { user.icon = defaultIcon; } } else { user.icon = qgetenv("HOME")+"/.face"; if(!QFile(user.icon).exists()) { user.icon = defaultIcon; } } user.name = name; user.path = ""; user.uid = getuid(); return user; } QString Users::getDefaultIcon() { return defaultIcon; } //https://stackoverflow.com/questions/20206376/ //how-do-i-extract-the-returned-data-from-qdbusmessage-in-a-qt-dbus-call void Users::loadUsers() { qDebug() << "loadUsers"; actService = new QDBusInterface(ACT_DBUS_SERVICE, ACT_DBUS_PATH, ACT_DBUS_INTERFACE, QDBusConnection::systemBus()); connect(actService, SIGNAL(UserAdded(const QDBusObjectPath&)), this, SLOT(onUserAdded(const QDBusObjectPath&))); connect(actService, SIGNAL(UserDeleted(const QDBusObjectPath&)), this, SLOT(onUserDeleted(const QDBusObjectPath&))); QDBusMessage ret = actService->call("ListCachedUsers"); QList outArgs = ret.arguments(); //(QVariant(QDBusArgument,)) QVariant first = outArgs.at(0); //QVariant(QDBusArgument,) const QDBusArgument &dbusArgs = first.value(); QDBusObjectPath path; dbusArgs.beginArray(); while (!dbusArgs.atEnd()) { dbusArgs >> path; getUser(path.path()); } dbusArgs.endArray(); } UserItem Users::getUser(const QString &path) { QDBusInterface iface(ACT_DBUS_SERVICE, path, DBUS_PROP_INTERFACE, QDBusConnection::systemBus()); QDBusMessage ret = iface.call("GetAll", ACT_USER_INTERFACE); QList outArgs = ret.arguments(); QVariant first = outArgs.at(0); const QDBusArgument &dbusArgs = first.value(); UserItem user; user.path = path; dbusArgs.beginMap(); while(!dbusArgs.atEnd()) { QString key; QVariant value; dbusArgs.beginMapEntry(); dbusArgs >> key >> value; if(key == "UserName") { user.name = value.toString(); } else if(key == "RealName") { user.realName = value.toString(); } else if(key == "IconFile") { user.icon = value.toString(); if(!QFile(user.icon).exists()) { user.icon = defaultIcon; } } else if(key == "Uid") { user.uid = value.toUInt(); } dbusArgs.endMapEntry(); } dbusArgs.endMap(); if(user.realName.isEmpty()) { user.realName = user.name; } users.push_back(user); return user; } void Users::onUserAdded(const QDBusObjectPath& path) { int index = findUserByPath(path.path()); if(index >=0 &&index= 0 && index. * **/ #ifndef SESSIONMANAGER_H #define SESSIONMANAGER_H #include #include class SessionManager : public QObject { Q_OBJECT public: explicit SessionManager(QObject *parent = nullptr); signals: private slots: void onStop(); void onEndSession(unsigned int flag); void onQueryEndSession(unsigned int flag); void endSessionResponse(); private: QDBusInterface *smInterface; QDBusInterface *clientInterface; QString clientId; }; #endif // SESSIONMANAGER_H ukui-biometric-auth/polkit-agent/src/mainwindow.h0000644000175000017500000000552714107167520021113 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include "biometric.h" #include "users.h" namespace Ui { class MainWindow; } class MainWindow : public QWidget { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void closeEvent(QCloseEvent *event); bool eventFilter(QObject *obj, QEvent *event); enum Mode{UNDEFINED, PASSWORD, BIOMETRIC, DEVICES}; void setIcon(const QString &iconName); void setHeader(const QString &text); void setUsers(const QStringList &usersList); void setDetails(const QString &subPid, const QString &callerPid, const QString &actionId, const QString &actionDesc, const QString vendorName, const QString vendorUrl); void setPrompt(const QString &text, bool echo); void setMessage(const QString &text); void setAuthResult(bool result, const QString &text=""); void clearEdit(); void switchAuthMode(Mode mode); void setDoubleAuth(bool val); void stopDoubleAuth(); QString check_is_pam_message(QString text); private: uid_t getUid(const QString &userName); void setMovie(); void setPixmap(); void startBioAuth(); void switchWidget(Mode mode); int enable_biometric_authentication(); private slots: void on_btnDetails_clicked(); void on_lePassword_returnPressed(); void on_btnBioAuth_clicked(); void on_cmbUsers_currentTextChanged(const QString &userName); void on_btnCancel_clicked(); void on_btnAuth_clicked(); void restart_bio_identify(); signals: void accept(const QString &text); void canceled(); void switchToPassword(); void switchToBiometric(); void userChanged(const QString &userName); private: Ui::MainWindow *ui; Users *users; QString userName; bool enableBioAuth; bool receiveBioPAM; BioDevices bioDevices; Mode authMode; BioDevicesWidget *widgetBioDevices; BioAuthWidget *widgetBioAuth; bool isFirst; bool useDoubleAuth; bool isbioSuccess; QMap m_failMap; int maxFailedTimes; bool isHiddenSwitchButton; }; #endif // MAINWINDOW_H ukui-biometric-auth/polkit-agent/src/PolkitAgent.cpp0000644000175000017500000000467514064326115021515 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include #include #include #include #include "PolkitListener.h" #include "generic.h" #include "sessionmanager.h" #include "biodevices.h" bool enableDebug; QString logPrefix; int main(int argc, char *argv[]) { enableDebug = true; logPrefix = "[ukui-polkit]:"; qInstallMessageHandler(outputMessage); qDebug() << "Polkit Agent Started"; #if(QT_VERSION>=QT_VERSION_CHECK(5,6,0)) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif QApplication agent(argc, argv); QString locale = QLocale::system().name(); qDebug() << "Language: " <. * **/ #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "generic.h" #define _(string) gettext(string) MainWindow::MainWindow(QWidget *parent) : QWidget(parent), ui(new Ui::MainWindow), users(new Users(this)), enableBioAuth(false), receiveBioPAM(false), authMode(UNDEFINED), useDoubleAuth(false), isbioSuccess(false) { ui->setupUi(this); setWindowTitle(tr("Authentication")); setWindowFlags(Qt::WindowStaysOnTopHint); widgetBioAuth = new BioAuthWidget(this); widgetBioDevices = new BioDevicesWidget(this); ui->formLayout->addWidget(widgetBioAuth); ui->formLayout->addWidget(widgetBioDevices); maxFailedTimes = bioDevices.getFailedTimes(); isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton(); if(isHiddenSwitchButton) widgetBioAuth->hidePasswdButton(); connect(widgetBioDevices, &BioDevicesWidget::deviceChanged, this, [&](const DeviceInfo &device){ widgetBioAuth->startAuth(getUid(userName), device); switchWidget(BIOMETRIC); }); connect(widgetBioDevices, &BioDevicesWidget::back, this, [&]{ switchWidget(BIOMETRIC); }); connect(&bioDevices, &BioDevices::deviceCountChanged, this, [&]{ widgetBioAuth->setMoreDevices(bioDevices.GetUserDevCount(getUid(userName)) > 1); }); connect(widgetBioAuth, &BioAuthWidget::authComplete, this, [&](uid_t uid, bool ret){ qDebug() << "biometric authentication complete: " << uid << ret; if(uid == getUid(userName) && ret) { if(useDoubleAuth){ isbioSuccess = true; emit switchToBiometric(); authMode = UNDEFINED; }else{ accept(BIOMETRIC_SUCCESS); } }else if(useDoubleAuth){ if(m_failMap.contains(getUid(userName))){ m_failMap[getUid(userName)] = m_failMap[getUid(userName)] + 1; }else{ m_failMap[getUid(userName)] = 1; } if(m_failMap[getUid(userName)] >= maxFailedTimes){ setMessage(tr("Too many unsuccessful attempts,please enter password.")); return ; } setMessage(tr("Fingerprint authentication failed, you still have %1 verification opportunities")\ .arg(maxFailedTimes - m_failMap[getUid(userName)])); // widgetBioAuth->startAuth(getUid(userName), *device); if(!isbioSuccess){ QTimer::singleShot(1000,this,SLOT(restart_bio_identify())); } } }); connect(widgetBioAuth, &BioAuthWidget::selectDevice, this, [&]{ //widgetBioDevices->init(getUid(userName)); switchWidget(DEVICES); }); connect(widgetBioAuth, &BioAuthWidget::switchToPassword, this, [&] { accept(BIOMETRIC_IGNORE); }); QFile qssFile(":/qss/src/main.qss"); qssFile.open(QIODevice::ReadOnly); setStyleSheet(qssFile.readAll()); qssFile.close(); ui->cmbUsers->hide(); ui->widgetDetails->hide(); ui->btnDetails->setIcon(QIcon(":/image/assets/arrow_right.svg")); ui->btnDetails->hide(); ui->lePassword->installEventFilter(this); switchWidget(UNDEFINED); } MainWindow::~MainWindow() { delete ui; } void MainWindow::restart_bio_identify() { DeviceInfo *device = bioDevices.getDefaultDevice(getUid(userName)); if(device){ widgetBioAuth->startAuth(getUid(userName), *device); setMessage(tr("Please enter your password or enroll your fingerprint ")); } } void MainWindow::closeEvent(QCloseEvent *event) { widgetBioAuth->stopAuth(); emit canceled(); return QWidget::closeEvent(event); } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if(obj == ui->lePassword){ if(event->type() == QEvent::KeyPress){ //禁止复制粘贴功能。 QKeyEvent *keyEvent = static_cast(event); if(keyEvent->matches(QKeySequence::Copy) || keyEvent->matches(QKeySequence::Cut) || keyEvent->matches(QKeySequence::Paste)){ event->ignore(); return true; } } } return false; } /*** main ***/ void MainWindow::on_cmbUsers_currentTextChanged(const QString &userName) { qDebug() << "user changed to " << userName; widgetBioAuth->stopAuth(); authMode=UNDEFINED; QList accountUsers = users->getUsers(); this->userName = userName; for(UserItem user:accountUsers){ if(user.realName == userName){ this->userName = user.name; } } ui->lblMessage->clear(); widgetBioDevices->init(getUid(this->userName)); emit userChanged(this->userName); } int MainWindow::enable_biometric_authentication() { char conf_file[] = GET_STR(CONFIG_FILE); FILE *file; char line[1024], is_enable[16]; int i; if((file = fopen(conf_file, "r")) == NULL){ return 0; } while(fgets(line, sizeof(line), file)) { i = sscanf(line, "EnableAuth=%s\n", is_enable); if(i > 0) { break; } } fclose(file); if(!strcmp(is_enable, "true")) return 1; return 0; } void MainWindow::on_btnDetails_clicked() { if(ui->widgetDetails->isHidden()) { ui->widgetDetails->show(); ui->btnDetails->setIcon(QIcon(":/image/assets/arrow_down.svg")); // resize(width(), height() + ui->widgetDetails->height()); } else { ui->widgetDetails->hide(); ui->btnDetails->setIcon(QIcon(":/image/assets/arrow_right.svg")); // resize(width(), height() - ui->widgetDetails->height()); } adjustSize(); } void MainWindow::on_btnCancel_clicked() { close(); } void MainWindow::on_btnAuth_clicked() { on_lePassword_returnPressed(); } /*** pagePassword ***/ void MainWindow::on_lePassword_returnPressed() { emit accept(ui->lePassword->text()); switchWidget(UNDEFINED); setMessage(tr("in authentication, please wait...")); } void MainWindow::on_btnBioAuth_clicked() { emit switchToBiometric(); authMode = BIOMETRIC; } /*** end of control's slot ***/ /*** public member ***/ void MainWindow::setIcon(const QString &iconName) { QIcon::setThemeName("ukui-icon-theme"); if(!QIcon::hasThemeIcon("ukui-polkit")) { QDir iconsDir("/usr/share/icons"); auto themesList = iconsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); qDebug() << themesList; for(auto theme : themesList) { QIcon::setThemeName(theme); if(QIcon::hasThemeIcon("ukui-polkit")) { qDebug() << theme << "has ukui-polkit icon"; break; } } } QPixmap icon = QIcon::fromTheme("ukui-polkit").pixmap(64, 64); QPixmap actionIcon = QIcon::fromTheme(iconName).pixmap(32, 32); QPainter painter; painter.begin(&icon); QRect rect(32, 32, 32, 32); painter.drawPixmap(rect, actionIcon); painter.end(); setWindowIcon(icon); ui->lblIcon->setPixmap(icon); } void MainWindow::setHeader(const QString &text) { ui->lblHeader->setText(text); ui->lblContent->setText(tr("An application is attempting to perform an action that requires privileges." " Authentication is required to perform this action.")); } void MainWindow::setUsers(const QStringList &usersList) { if(usersList.isEmpty()) return; if(usersList.size() == 1) { UserItem user = users->getUserByName(usersList.at(0)); if(user.realName != ""){ userName = user.realName; }else{ userName = usersList.at(0); } } QList accountUsers = users->getUsers(); for(QString identifyUser:usersList){ for(UserItem user:accountUsers){ if(identifyUser == user.name){ if(user.realName != "") ui->cmbUsers->addItem(user.realName); else ui->cmbUsers->addItem(user.name); } } } ui->cmbUsers->show(); } void MainWindow::setDetails(const QString &subPid, const QString &callerPid, const QString &actionId, const QString &actionDesc, const QString vendorName, const QString vendorUrl) { ui->lblSubjectPid->setText(subPid); ui->lblCallerPid->setText(callerPid); ui->lblActionId->setText(actionId); ui->lblActionDesc->setText(actionDesc); QString vendor = QString("%2").arg(vendorUrl).arg(vendorName); ui->lblVendor->setText(vendor); } void MainWindow::setPrompt(const QString &text, bool echo) { QString prompt = text; if(text == "Password: "){ prompt = tr("Password: "); if(useDoubleAuth && widgetBioAuth && widgetBioAuth->isAuthenticating()){ uid_t m_uid = getUid(userName); if(!m_failMap.contains(m_uid) || m_failMap[m_uid] < maxFailedTimes) setMessage(tr("Please enter your password or enroll your fingerprint ")); } } ui->lblPrompt->setText(prompt); ui->lePassword->setEchoMode(echo ? QLineEdit::Normal : QLineEdit::Password); switchWidget(PASSWORD); } /* 转换pam英文提示,目前转换的就3个翻译 Authenticated failed, account locked! Authenticated failed, 1 login attemps left Account locked, 4 minutes left */ QString MainWindow::check_is_pam_message(QString text) { setlocale(LC_ALL,""); bindtextdomain("Linux-PAM","/usr/share/locale"); bind_textdomain_codeset("Linux-PAM","UTF-8"); textdomain("Linux-PAM"); char* str; QString strTrans = ""; QByteArray ba = text.toLatin1(); // must str=ba.data(); int a,b; if(sscanf(str,"Authenticated failed, %d login attemps left",&a)) sprintf(str,_("Authenticated failed, %d login attemps left"),a); else if(text.contains("days",Qt::CaseSensitive) && sscanf(str,"Account locked, %d days left",&a)){ strTrans = tr("Account locked,") + QString("%1 ").arg(a) + tr("days left"); return strTrans; } else if(text.contains("hours",Qt::CaseSensitive) && sscanf(str,"Account locked, %d hours left",&a)){ strTrans = tr("Account locked,") + QString("%1 ").arg(a) + tr("hours left"); return strTrans; } else if(text.contains("minutes",Qt::CaseSensitive) && sscanf(str,"Account locked, %d minutes left",&a)){ strTrans = tr("Account locked,") + QString("%1 ").arg(a) + tr("minutes left"); return strTrans; } else if(text.contains("seconds",Qt::CaseSensitive) && sscanf(str,"Account locked, %d seconds left",&a)){ strTrans = tr("Account locked,") + QString("%1 ").arg(a) + tr("seconds left"); return strTrans; } else{ str = _(str); } qDebug()<<"str = "<check_is_pam_message(text); ui->lblMessage->setText(text); } void MainWindow::setAuthResult(bool result, const QString &text) { QString message = text; if(!result && text.isEmpty()) message = tr("Authentication failed, please try again."); if(authMode == PASSWORD) ui->lblMessage->setText(message); // else if(authMode == BIOMETRIC) // ui->lblBioNotify->setText(message); switchWidget(PASSWORD); } void MainWindow::clearEdit() { ui->lePassword->setText(""); } void MainWindow::switchAuthMode(Mode mode) { if(useDoubleAuth && isbioSuccess){ accept(BIOMETRIC_SUCCESS); return ; } int uid = getUid(userName); int count = bioDevices.GetUserDevCount(getUid(userName)); enableBioAuth = count > 0; if(!enable_biometric_authentication()){ enableBioAuth = false; } if(useDoubleAuth && m_failMap.contains(uid) && m_failMap[uid] >= maxFailedTimes){ enableBioAuth = false; } // if(mode == BIOMETRIC && enableBioAuth == false) // useDoubleAuth = false; switch(mode){ case PASSWORD: { qDebug() << "switch to password"; authMode = mode; if(!enableBioAuth || !receiveBioPAM || useDoubleAuth) { ui->btnBioAuth->hide(); }else{ ui->btnBioAuth->show(); } if(isHiddenSwitchButton) ui->btnBioAuth->hide(); if(enableBioAuth && useDoubleAuth){ DeviceInfo *device = bioDevices.getDefaultDevice(getUid(userName)); if(device){ widgetBioAuth->startAuth(getUid(userName), *device); } } } break; case BIOMETRIC: { qDebug() << "switch to biometric"; receiveBioPAM = true; if(authMode == PASSWORD) { emit accept(BIOMETRIC_IGNORE); return; }else if(!enableBioAuth){ qDebug() << "It doesn't meet the condition for enabling biometric authentication, switch to password."; emit accept(BIOMETRIC_IGNORE); return; } else if(authMode == BIOMETRIC) { DeviceInfo *device = bioDevices.getDefaultDevice(getUid(userName)); if(!device) device = bioDevices.getFirstDevice(); if(device) { if(useDoubleAuth){ emit accept(BIOMETRIC_IGNORE); widgetBioAuth->startAuth(getUid(userName), *device); return; }else{ widgetBioAuth->startAuth(getUid(userName), *device); widgetBioAuth->setMoreDevices(count > 1); } } authMode = BIOMETRIC; } else if(authMode == UNDEFINED){ authMode = BIOMETRIC; if(enableBioAuth) { qDebug() << "enable biometric authenticaion"; DeviceInfo *device = bioDevices.getDefaultDevice(getUid(userName)); if(device) { if(useDoubleAuth){ emit accept(BIOMETRIC_IGNORE); widgetBioAuth->startAuth(getUid(userName), *device); return; }else{ widgetBioAuth->startAuth(getUid(userName), *device); widgetBioAuth->setMoreDevices(count > 1); } } else { qDebug() << "No default device, switch to password"; emit accept(BIOMETRIC_IGNORE); return; } } else { /* pass biometric's pam module if there are not available devices */ qDebug() << "It doesn't meet the condition for enabling biometric authentication, switch to password."; emit accept(BIOMETRIC_IGNORE); return; } } } break; default: break; } switchWidget(mode); } /*** end of public memeber ***/ /*** private member ***/ uid_t MainWindow::getUid(const QString &userName) { struct passwd *pwd = getpwnam(userName.toStdString().c_str()); if(pwd == NULL) { qWarning() << "getpwnam error: " << strerror(errno); return -1; } return pwd->pw_uid; } void MainWindow::setDoubleAuth(bool val){ useDoubleAuth = val; } void MainWindow::stopDoubleAuth() { if(useDoubleAuth && widgetBioAuth) widgetBioAuth->stopAuth(); } void MainWindow::switchWidget(Mode mode) { ui->widgetPasswdAuth->hide(); ui->btnAuth->hide(); widgetBioAuth->hide(); widgetBioDevices->hide(); switch(mode){ case PASSWORD: setMinimumWidth(420); ui->widgetPasswdAuth->show(); ui->lePassword->setFocus(); ui->lePassword->setAttribute(Qt::WA_InputMethodEnabled, false); ui->btnAuth->show(); break; case BIOMETRIC: setMaximumWidth(380); widgetBioAuth->show(); break; case DEVICES: widgetBioDevices->show(); default: break; } adjustSize(); } /*** end of private member ***/ ukui-biometric-auth/polkit-agent/src/PolkitListener.cpp0000644000175000017500000002574514107167520022246 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PolkitListener.h" #include "mainwindow.h" #include "generic.h" PolkitListener::PolkitListener(QObject *parent) : Listener(parent), inProgress(false), currentIdentity(0), mainWindow(nullptr) { } PolkitListener::~PolkitListener() { } /* initiateAuthentication message from polkit */ void PolkitListener::initiateAuthentication( const QString &actionId, const QString &message, const QString &iconName, const PolkitQt1::Details &details, const QString &cookie, const PolkitQt1::Identity::List &identities, PolkitQt1::Agent::AsyncResult *result) { if(inProgress){ result->setError(tr("Another client is already authenticating, please try again later.")); result->setCompleted(); qDebug() << "Another client is already authenticating, please try again later."; return; } QStringList usersList; QString subjectPid, callerPid; PolkitQt1::ActionDescription actionDesc; QString username = getenv("USER"); for(auto identity : identities){ if(identity.toString().remove("unix-user:") == username) usersList.prepend(identity.toString().remove("unix-user:")); else usersList.append(identity.toString().remove("unix-user:")); } subjectPid = details.lookup("polkit.subject-pid"); callerPid = details.lookup("polkit.caller-pid"); /* find action description for actionId */ foreach(const PolkitQt1::ActionDescription &desc, PolkitQt1::Authority::instance()->enumerateActionsSync()) { if (actionId == desc.actionId()) { actionDesc = desc; qDebug() << "Action description has been found" ; break; } } qDebug() << "Initiating authentication"; qDebug() << "icon name: " << iconName; qDebug() << "identities: " << usersList; qDebug() << "message: " << message; qDebug() << "action id: " << actionId; qDebug() << "polkit.subject-pid" << subjectPid; qDebug() << "polkit.caller-pid" << callerPid; qDebug() << "action: " << actionDesc.description(); qDebug() << "Vendor:" << actionDesc.vendorName() << actionDesc.vendorUrl(); this->inProgress = true; this->identities = identities; this->cookie = cookie; this->result = result; session.clear(); if (identities.length() == 1) { this->currentIdentity = identities[0]; } else { currentIdentity = identities[0]; } /* Create the polkit window */ mainWindow = new MainWindow; mainWindow->setIcon(iconName); mainWindow->setHeader(message); mainWindow->setUsers(usersList); mainWindow->setDetails(subjectPid, callerPid, actionDesc.actionId(), actionDesc.description(), actionDesc.vendorName(), actionDesc.vendorUrl()); /* set the position of the mainwindow */ QPoint pos = QCursor::pos(); for(auto screen : QGuiApplication::screens()) { if(screen->geometry().contains(pos)) { mainWindow->move(screen->geometry().left() + (screen->geometry().width() - mainWindow->width()) / 2, screen->geometry().top() + (screen->geometry().height() - mainWindow->height()) / 2); } } connect(mainWindow, &MainWindow::accept, this, &PolkitListener::onResponse); connect(mainWindow, &MainWindow::canceled, this, [&]{ wasCancelled = true; if(!session.isNull()) { session.data()->cancel(); } }); connect(mainWindow, &MainWindow::switchToBiometric, this, [&]{ wasSwitchToBiometric = true; startAuthentication(); }); connect(mainWindow, &MainWindow::userChanged, this, [&](const QString &userName){ for(int i = 0; i < this->identities.size(); i++) { auto identity = this->identities.at(i); if(identity.toString().remove("unix-user:") == userName) { this->currentIdentity = this->identities.at(i); numTries = 0; startAuthentication(); break; } } }); numTries = 0; wasCancelled = false; wasSwitchToBiometric = false; mainWindow->userChanged(usersList.at(0)); } static int get_pam_tally(int *deny, int *unlock_time) { char buf[128]; FILE *auth_file; if( (auth_file = fopen("/etc/pam.d/common-auth", "r")) == NULL) return -1; while(fgets(buf, sizeof(buf), auth_file)) { if(strlen(buf) == 0 || buf[0] == '#') continue; if(!strstr(buf, "deny")) continue; char *ptr = strtok(buf, " \t"); while(ptr) { if(strncmp(ptr, "deny=", 5)==0){ sscanf(ptr, "deny=%d", deny); //gs_debug("-------------------- deny=%d", *deny); } if(strncmp(ptr, "unlock_time=", 12)==0){ sscanf(ptr, "unlock_time=%d", unlock_time); //gs_debug("-------------------- unlock_time=%d", *unlock_time); } ptr = strtok(NULL, " \t"); } return 1; } return 0; } void PolkitListener::finishObtainPrivilege() { /* Number of tries increase only when some user is selected */ if (currentIdentity.isValid()) { numTries++; } qDebug().noquote() << QString("Finishing obtaining " "privileges (G:%1, C:%2, D:%3).") .arg(gainedAuthorization) .arg(wasCancelled) .arg(mainWindow != NULL); if (!gainedAuthorization && !wasCancelled && (mainWindow != NULL)) { int deny = 0, unlock_time = 0; mainWindow->stopDoubleAuth(); if(!get_pam_tally(&deny, &unlock_time)||(deny == 0 &&unlock_time == 0)) { if(!wasSwitchToBiometric){ mainWindow->setAuthResult(gainedAuthorization, tr("Authentication failure, please try again.")); } startAuthentication(); return; } else { startAuthentication(); return; } } if (mainWindow) { mainWindow->hide(); mainWindow->stopDoubleAuth(); mainWindow->deleteLater(); mainWindow = NULL; } if (!session.isNull()) { session.data()->result()->setCompleted(); } else { result->setCompleted(); } session.data()->deleteLater(); this->inProgress = false; qDebug() << "Finish obtain authorization:" << gainedAuthorization; } void establishToBioPAM() { FILE *file; const char *data = "polkit-ukui-authentication-agent-1"; if( (file = fopen(BIO_COM_FILE, "w")) == NULL){ qWarning() << "open communication file failed: " << strerror(errno); return; } if(fputs(data, file) == EOF) { qWarning() << "write to communication file error: " << strerror(errno); } fclose(file); } void PolkitListener::startAuthentication() { qDebug() << "start authenticate user " << currentIdentity.toString(); if(!session.isNull()) { session.data()->deleteLater(); } /* We will create a new session only when some user is selected */ if (currentIdentity.isValid()) { establishToBioPAM(); session = new Session(currentIdentity, cookie, result); connect(session.data(), SIGNAL(request(QString, bool)), this, SLOT(onShowPrompt(QString,bool))); connect(session.data(), SIGNAL(completed(bool)), this, SLOT(onAuthCompleted(bool))); connect(session.data(), SIGNAL(showError(QString)), this, SLOT(onShowError(QString))); connect(session.data(), SIGNAL(showInfo(QString)), this, SLOT(onShowError(QString))); session.data()->initiate(); } mainWindow->clearEdit(); } void PolkitListener::onShowPrompt(const QString &prompt, bool echo) { qDebug() << "Prompt: " << prompt << "echo: " << echo; if(prompt == BIOMETRIC_PAM) { mainWindow->setDoubleAuth(false); mainWindow->switchAuthMode(MainWindow::BIOMETRIC); }else if(prompt == BIOMETRIC_PAM_DOUBLE){ mainWindow->setDoubleAuth(true); mainWindow->switchAuthMode(MainWindow::BIOMETRIC); //这时候不需要显示授权弹窗,下一次收到prompt请求的时候再显示 return; } else { mainWindow->switchAuthMode(MainWindow::PASSWORD); mainWindow->setPrompt(prompt, echo); } mainWindow->show(); QPoint pos = QCursor::pos(); for(auto screen : QGuiApplication::screens()) { if(screen->geometry().contains(pos)) { mainWindow->move(screen->geometry().left() + (screen->geometry().width() - mainWindow->width()) / 2, screen->geometry().top() + (screen->geometry().height() - mainWindow->height()) / 2); } } mainWindow->activateWindow(); } //目前返回的pam错误就onShowError,onShowInfo两类 void PolkitListener::onShowError(const QString &text) { qDebug() << "[Polkit]:" << "Error:" << text; if(mainWindow){ QString strText = mainWindow->check_is_pam_message(text); mainWindow->setMessage(strText); } } void PolkitListener::onShowInfo(const QString &text) { qDebug() << "[Polkit]:" << "Info:" << text; if(mainWindow){ QString strText = mainWindow->check_is_pam_message(text); mainWindow->setMessage(strText); } } void PolkitListener::onResponse(const QString &text) { session.data()->setResponse(text); } void PolkitListener::onAuthCompleted(bool gainedAuthorization) { qDebug() << "completed: " << gainedAuthorization; this->gainedAuthorization = gainedAuthorization; finishObtainPrivilege(); } bool PolkitListener::initiateAuthenticationFinish() { qDebug() << "initiateAuthenticationFinish."; return true; } void PolkitListener::cancelAuthentication() { wasCancelled = true; qDebug() << "cancelAuthentication."; finishObtainPrivilege(); } ukui-biometric-auth/polkit-agent/src/users.h0000644000175000017500000000325214064326115020070 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef USERS_H #define USERS_H #include struct UserItem { QString name; QString realName; QString icon; quint64 uid; QString path; //accounts service path friend QDebug operator<<(QDebug stream, const UserItem &user); }; class QDBusInterface; class QDBusObjectPath; class Users : public QObject { Q_OBJECT public: explicit Users(QObject *parent = nullptr); QList getUsers(); UserItem getUserByName(const QString &name); QString getDefaultIcon(); private: void loadUsers(); UserItem getUser(const QString &path); int findUserByPath(const QString &path); private Q_SLOTS: void onUserAdded(const QDBusObjectPath& path); void onUserDeleted(const QDBusObjectPath& path); Q_SIGNALS: void userAdded(const UserItem &user); void userDeleted(const UserItem &user); private: QDBusInterface *actService; QList users; QString defaultIcon; }; #endif // USERS_H ukui-biometric-auth/polkit-agent/src/PolkitListener.h0000644000175000017500000000375614064326115021710 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef POLKITLISTENER_H #define POLKITLISTENER_H #include #include #include "mainwindow.h" using namespace PolkitQt1::Agent; class PolkitListener : public Listener { Q_OBJECT public: PolkitListener(QObject *parent = 0); virtual ~PolkitListener(); public slots: void initiateAuthentication(const QString &actionId, const QString &message, const QString &iconName, const PolkitQt1::Details &details, const QString &cookie, const PolkitQt1::Identity::List &identities, PolkitQt1::Agent::AsyncResult *result); bool initiateAuthenticationFinish(); void cancelAuthentication(); void finishObtainPrivilege(); private: bool gainedAuthorization; bool wasCancelled; bool wasSwitchToBiometric; bool inProgress; int numTries; QPointer session; PolkitQt1::Identity::List identities; PolkitQt1::Identity currentIdentity; PolkitQt1::Agent::AsyncResult *result; QString cookie; MainWindow *mainWindow; private slots: void startAuthentication(); void onShowPrompt(const QString &prompt, bool echo); void onShowError(const QString &text); void onShowInfo(const QString &text); void onResponse(const QString &text); void onAuthCompleted(bool); }; #endif /* POLKITLISTENER_H */ ukui-biometric-auth/polkit-agent/src/types.h0000644000175000017500000000422014064326115020067 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #ifndef TYPES_H #define TYPES_H /* https://www.narf.ssji.net/~shtrom/wiki/projets/gnomescreensavernosession */ enum SessionStatus { SESSION_AVAILABLE = 0, SESSION_INVISIBLE = 1, SESSION_BUSY = 2, SESSION_IDLE = 3 }; enum ScreenStatus { UNDEFINED = 0x00, SCREEN_SAVER = 0x01, SCREEN_LOCK = 0x02 }; #define SM_DBUS_SERVICE "org.gnome.SessionManager" #define SM_DBUS_PATH "/org/gnome/SessionManager/Presence" #define SM_DBUS_INTERFACE "org.gnome.SessionManager.Presence" #define DM_DBUS_SERVICE "org.freedesktop.DisplayManager" #define DM_DBUS_PATH "/org/freedesktop/DisplayManager" #define DM_DBUS_INTERFACE "org.freedesktop.DisplayManager" #define DM_SEAT_INTERFACE "org.freedesktop.DisplayManager.Seat" #define ACT_DBUS_SERVICE "org.freedesktop.Accounts" #define ACT_DBUS_PATH "/org/freedesktop/Accounts" #define ACT_DBUS_INTERFACE "org.freedesktop.Accounts" #define ACT_USER_INTERFACE "org.freedesktop.Accounts.User" #define DBUS_PROP_INTERFACE "org.freedesktop.DBus.Properties" #define SS_DBUS_SERVICE "org.ukui.ScreenSaver" #define SS_DBUS_PATH "/" #define SS_DBUS_INTERFACE "org.ukui.ScreenSaver" #define BIO_ERROR -1 #define BIO_FAILED 0 #define BIO_SUCCESS 1 #define BIO_IGNORE 2 #define BIOMETRIC_PAM "BIOMETRIC_PAM" #define BIOMETRIC_IGNORE "BIOMETRIC_IGNORE" #define BIOMETRIC_SUCCESS "BIOMETRIC_SUCCESS" #define BIOMETRIC_FAILED "BIOMETRIC_FAILED" #endif // TYPES_H ukui-biometric-auth/polkit-agent/src/sessionmanager.cpp0000644000175000017500000000603414064326115022301 0ustar fengfeng/* * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. * * 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, 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 . * **/ #include "sessionmanager.h" #include #include #include #include #define SM_DBUS_SERVICE "org.gnome.SessionManager" #define SM_DBUS_PATH "/org/gnome/SessionManager" #define SM_DBUS_INTERFACE "org.gnome.SessionManager" #define SM_DBUS_CLIENT_INTERFACE "org.gnome.SessionManager.ClientPrivate" SessionManager::SessionManager(QObject *parent) : QObject(parent) { smInterface = new QDBusInterface(SM_DBUS_SERVICE, SM_DBUS_PATH, SM_DBUS_INTERFACE, QDBusConnection::sessionBus()); QString appId("polkit-ukui-authentication-agent-1.desktop"); QString clientStartupId(qgetenv("DESKTOP_AUTOSTART_ID")); QDBusReply reply = smInterface->call("RegisterClient", appId, clientStartupId); if(!reply.isValid()) { qWarning() << "Register Client to gnome session failed"; } clientId = reply.value().path(); qDebug() << "Register Client to gnome session: " << reply.value().path(); clientInterface = new QDBusInterface(SM_DBUS_SERVICE, clientId, SM_DBUS_CLIENT_INTERFACE, QDBusConnection::sessionBus()); qDebug() << clientInterface->isValid(); QDBusConnection conn = clientInterface->connection(); conn.connect(SM_DBUS_SERVICE, clientId, SM_DBUS_CLIENT_INTERFACE, "Stop", this, SLOT(onStop())); conn.connect(SM_DBUS_SERVICE, clientId, SM_DBUS_CLIENT_INTERFACE, "EndSession", this, SLOT(onEndSession(unsigned int))); conn.connect(SM_DBUS_SERVICE, clientId, SM_DBUS_CLIENT_INTERFACE, "QueryEndSession", this, SLOT(onQueryEndSession(unsigned int))); } void SessionManager::onStop() { QApplication::quit(); } void SessionManager::onEndSession(unsigned int flag) { endSessionResponse(); } void SessionManager::onQueryEndSession(unsigned int flag) { endSessionResponse(); QApplication::quit(); } void SessionManager::endSessionResponse() { QDBusMessage msg = clientInterface->call("EndSessionResponse", true, ""); if(msg.type() == QDBusMessage::ErrorMessage) qDebug() << "Failed to call EndSessionResponse " << msg.errorMessage(); } ukui-biometric-auth/polkit-agent/i18n_ts/0000755000175000017500000000000014107167520017253 5ustar fengfengukui-biometric-auth/polkit-agent/i18n_ts/es.ts0000644000175000017500000000613614064326115020237 0ustar fengfeng MainWindow Form Formar Biometric Biometrico Details Detalles Polkit.subject-pid: Polkit.subject-pid: Vendor: Vendedor: Description: Descripción: Polkit.caller-pid: Polkit.caller-pid: Action: Acción: Cancel Cancelar Authenticate Autenticar Authentication Autenticación in authentication, please wait... En autenticación, por favor espere ... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Una aplicación está intentando realizar una acción que requiere privilegios. Se requiere autenticación para realizar esta acción. Password: Contraseña: Authentication failed, please try again. Autenticación fallida. Por favor intente de nuevo. Too many unsuccessful attempts,please enter password. Fingerprint authentication failed, you still have %1 verification opportunities Please enter your password or enroll your fingerprint PolkitListener Another client is already authenticating, please try again later. Otro cliente ya se está autenticando, inténtalo de nuevo más tarde. Authentication failure, please try again. Fallo de autenticación, por favor intente de nuevo. ukui-biometric-auth/polkit-agent/i18n_ts/pt.ts0000644000175000017500000000613514064326115020252 0ustar fengfeng MainWindow Form Formato Biometric Biométrico Details Detalhes Polkit.subject-pid: Polkit.subject-pid: Vendor: Fornecedor: Description: Descrição: Polkit.caller-pid: Polkit.caller-pid: Action: Açao: Cancel Cancelar Authenticate Autenticar Authentication Autenticação in authentication, please wait... na autenticação, por favor aguarde ... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Um aplicativo está tentando executar uma ação que requer privilégios. A autenticação é necessária para executar esta ação. Password: Senha: Authentication failed, please try again. Autenticação falhou. Por favor, tente novamente. Too many unsuccessful attempts,please enter password. Fingerprint authentication failed, you still have %1 verification opportunities Please enter your password or enroll your fingerprint PolkitListener Another client is already authenticating, please try again later. Outro cliente já está autenticando, por favor, tente novamente mais tarde. Authentication failure, please try again. Falha de autenticação, por favor, tente novamente. ukui-biometric-auth/polkit-agent/i18n_ts/zh_CN.ts0000644000175000017500000001713314107167520020631 0ustar fengfeng MainWindow Authentication 授权 Fingerprint authentication failed, you still have %1 verification opportunities 指纹验证失败,您还有%1次尝试机会 Form More 更多 Restart 重新开始 Password 密码 Biometric 使用生物识别 DeviceType: 设备类型: Back 返回 Details 详细 Action Id: 动作: Description: 描述: Polkit.subject-pid: Polkit.subject-pid: Retry 重试 Device types: 设备类型: Vendor: 发行商: Action: 动作: Polkit.caller-pid: Polkit.caller-pid: Cancel 取消 Authenticate 授权 Auth 授权 Too many unsuccessful attempts,please enter password. 指纹验证失败达最大次数,请使用密码解锁 in authentication, please wait... 认证中,请稍等... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. 一个程序正试图执行一个需要特权的动作。要求授权以执行该动作。 Password: 密码: Please enter your password or enroll your fingerprint 请输入密码或者录入指纹 _Password: 密码: _Password: 密码: Authentication failed, please try again. 认证失败,请重试。 days left 天后解锁 hours left 小时后解锁 minutes left 分钟后解锁 seconds left 秒后解锁 Account locked, 账户已锁定, Password cannot be empty 密码不能为空 Authentication failed, please try again 认证失败,请重试 PolkitListener Another client is already authenticating, please try again later. 有另外一个客户端正在认证,请稍后重试。 Authentication failure, please try again. 认证失败,请重试。 Account locked %1 minutes due to %2 fail attempts 账户锁定%1分钟由于%2次错误尝试 Authentication failure,there are still %1 remaining opportunities 认证失败,还剩余%1次尝试机会 QObject FingerPrint 指纹 FingerVein 指静脉 Iris 虹膜 Face 人脸 VoicePrint 声纹 ukui-biometric-auth/polkit-agent/i18n_ts/tr.ts0000644000175000017500000001615214064326115020254 0ustar fengfeng MainWindow Authentication Kimlik Doğrulama Fingerprint authentication failed, you still have %1 verification opportunities Form More Daha Fazla Restart Yeniden Başlat Password Parola Biometric Biyometrik DeviceType: Aygıt Türü: Back Geri Details Ayrıntılar Action Id: İşlem Kimliği: Description: Açıklama: Polkit.subject-pid: Polkit.subject-pid: Retry Yeniden Dene Device types: Aygıt türü: Vendor: Vendor: Action: Eylem: Polkit.caller-pid: Polkit.caller-pid: Cancel İptal Authenticate Kimlik Doğrulaması Auth Kimlik Doğrulaması Too many unsuccessful attempts,please enter password. Please enter your password or enroll your fingerprint in authentication, please wait... kimlik doğrulanırken lütfen bekleyin ... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Bir uygulama, ayrıcalıklar gerektiren bir eylem gerçekleştirmeye çalışıyor. Bu işlemi gerçekleştirmek için kimlik doğrulaması gerekiyor. Password: Parola: _Password: _Parola: _Password: _Parola: Authentication failed, please try again. Kimlik doğrulama başarısız, lütfen tekrar deneyin. Authentication failed, please try again Kimlik doğrulama başarısız, lütfen tekrar deneyin PolkitListener Another client is already authenticating, please try again later. Başka bir hesap zaten kimlik doğrulaması yapıyor, lütfen daha sonra tekrar deneyin. Authentication failure, please try again. Kimlik doğrulama hatalı, lütfen tekrar deneyin. Account locked %1 minutes due to %2 fail attempts %2 başarısız denemeden dolayı hesap %1 dakika kilitlendi Authentication failure,there are still %1 remaining opportunities Kimlik doğrulama hatası, %1 hakkınız kaldı QObject FingerPrint Parmak İzi FingerVein Damar İzi Iris Göz Face Yüz Tanıma VoicePrint Ses İzi ukui-biometric-auth/polkit-agent/i18n_ts/ru.ts0000644000175000017500000000667314064326115020264 0ustar fengfeng MainWindow Form форма Biometric Биометрические Details Детали Polkit.subject-pid: Polkit.subject-PID: Vendor: Производитель: Description: Описание: Polkit.caller-pid: Polkit.caller-PID: Action: Действие: Cancel Отмена Authenticate проверять подлинность Authentication Аутентификация in authentication, please wait... в аутентификации, пожалуйста, подождите ... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Приложение пытается выполнить действие, требующее привилегий. Для выполнения этого действия требуется аутентификация. Password: Пароль: Authentication failed, please try again. Ошибка аутентификации. Пожалуйста, попробуйте еще раз. Too many unsuccessful attempts,please enter password. Fingerprint authentication failed, you still have %1 verification opportunities Please enter your password or enroll your fingerprint PolkitListener Another client is already authenticating, please try again later. Другой клиент уже аутентифицируется, повторите попытку позже. Authentication failure, please try again. Ошибка аутентификации, повторите попытку. ukui-biometric-auth/polkit-agent/i18n_ts/bo.ts0000644000175000017500000001033214064326115020221 0ustar fengfeng MainWindow Form Biometric Details Polkit.subject-pid: Vendor: Description: Polkit.caller-pid: Action: Cancel Authenticate Authentication Too many unsuccessful attempts,please enter password. Fingerprint authentication failed, you still have %1 verification opportunities Please enter your password or enroll your fingerprint in authentication, please wait... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Password: Authentication failed, please try again. PolkitListener Another client is already authenticating, please try again later. Authentication failure, please try again. ukui-biometric-auth/polkit-agent/i18n_ts/fr.ts0000644000175000017500000000620414064326115020233 0ustar fengfeng MainWindow Form Forme Biometric Biométrique Details Détails Polkit.subject-pid: Polkit.subject-pid: Vendor: Vendeur: Description: La description: Polkit.caller-pid: Polkit.caller-pid: Action: Action: Cancel Annuler Authenticate Authentifier Authentication Authentification in authentication, please wait... en cours d'authentification, veuillez patienter ... An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. Une application tente d'exécuter une action nécessitant des privilèges. Une authentification est requise pour effectuer cette action. Password: Mot de passe: Authentication failed, please try again. Authentification échouée. Veuillez réessayer. Too many unsuccessful attempts,please enter password. Fingerprint authentication failed, you still have %1 verification opportunities Please enter your password or enroll your fingerprint PolkitListener Another client is already authenticating, please try again later. Un autre client s'authentifie déjà. Veuillez réessayer ultérieurement. Authentication failure, please try again. Échec de l'authentification, veuillez réessayer.