initial release 0.5.0 BETA
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/src/keepass2android/todos.cs
|
||||
/src/keepass2android/obj
|
||||
/src/keepass2android/bin
|
||||
/src/KeePassLib2Android/bin
|
5
CONTRIBUTORS
Normal file
@ -0,0 +1,5 @@
|
||||
Author of Keepass2Android: Philipp Crocoll
|
||||
Author of KeePass (KP2A contains the KeePassLib): Dominik Reichl
|
||||
Author of Keepassdroid (ported as base for UI): Brian Pellin
|
||||
See https://github.com/bpellin/keepassdroid/blob/master/CONTRIBUTORS
|
||||
for further Contributors of Keepassdroid.
|
339
COPYING.gpl-2.0
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
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
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision 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, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This 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.
|
132
LICENSE
Normal file
@ -0,0 +1,132 @@
|
||||
Files under src/KeepassLib2Android: GPL-v2, Copyright Dominik Reichl (Modifications Copyright by Philipp Crocoll)
|
||||
|
||||
---
|
||||
|
||||
Files under src/keepass2android* except under src/keepass2android/Resources/drawable*:
|
||||
|
||||
Copyright Philipp Crocoll <philipp.crocoll@web.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
Files ic00.png to ic61.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
TITLE: NUVOLA ICON THEME for KDE 3.x
|
||||
AUTHOR: David Vignoni | ICON KING
|
||||
SITE: http://www.icon-king.com
|
||||
MAILING LIST: http://mail.icon-king.com/mailman/listinfo/nuvola_icon-king.com
|
||||
|
||||
Copyright (c) 2003-2004 David Vignoni.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation,
|
||||
version 2.1 of the License.
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#######**** NOTE THIS ADD-ON ****#######
|
||||
The GNU Lesser General Public License or LGPL is written for software libraries
|
||||
in the first place. The LGPL has to be considered valid for this artwork
|
||||
library too.
|
||||
Nuvola icon theme for KDE 3.x is a special kind of software library, it is an
|
||||
artwork library, it's elements can be used in a Graphical User Interface, or
|
||||
GUI.
|
||||
Source code, for this library means:
|
||||
- raster png image* .
|
||||
The LGPL in some sections obliges you to make the files carry
|
||||
notices. With images this is in some cases impossible or hardly usefull.
|
||||
With this library a notice is placed at a prominent place in the directory
|
||||
containing the elements. You may follow this practice.
|
||||
The exception in section 6 of the GNU Lesser General Public License covers
|
||||
the use of elements of this art library in a GUI.
|
||||
dave [at] icon-king.com
|
||||
|
||||
Date: 15 october 2004
|
||||
Version: 1.0
|
||||
|
||||
DESCRIPTION:
|
||||
|
||||
Icon theme for KDE 3.x.
|
||||
Icons where designed using Adobe Illustrator, and then exported to PNG format.
|
||||
Icons shadows and minor corrections were done using Adobe Photoshop.
|
||||
Kiconedit was used to correct some 16x16 and 22x22 icons.
|
||||
|
||||
LICENSE
|
||||
|
||||
Released under GNU Lesser General Public License (LGPL)
|
||||
Look at the license.txt file.
|
||||
|
||||
CONTACT
|
||||
|
||||
David Vignoni
|
||||
e-mail : david [at] icon-king.com
|
||||
ICQ : 117761009
|
||||
http: http://www.icon-king.com
|
||||
|
||||
---
|
||||
|
||||
Files ic62.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
Based on http://de.wikipedia.org/w/index.php?title=Datei:Tux.svg&filetimestamp=20090927073505
|
||||
|
||||
The copyright holder of this file allows anyone to use it for any purpose,
|
||||
provided that the copyright holders Larry Ewing, Simon Budig and
|
||||
Anja Gerwinski are mentioned.
|
||||
|
||||
---
|
||||
|
||||
Files ic63.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
Based on http://en.wikipedia.org/wiki/File:ASF-logo.svg
|
||||
|
||||
Apache logo
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License. You may
|
||||
obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations under
|
||||
the License.
|
||||
|
||||
---
|
||||
|
||||
Files ic64.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
!!! Not included yet !!!
|
||||
|
||||
---
|
||||
|
||||
Files ic65.png, ic67.png and ic68.png under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
Created by Tobias Selig and licensed under the terms of the GPLv2 or GPLv3.
|
||||
|
||||
---
|
||||
|
||||
File ic66.png under under src/keepass2android/Resources/drawable, src/keepass2android/Resources/drawable-hdpi and src/keepass2android/Resources/drawable-ldpi
|
||||
|
||||
Based on http://commons.wikimedia.org/wiki/File:Dollar_symbol_gold.svg
|
||||
|
||||
Author: Rugby471
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document under
|
||||
the terms of the GNU Free Documentation License, Version 1.2 or any later
|
||||
version published by the Free Software Foundation; with no Invariant Sections,
|
||||
no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is
|
||||
included in the section entitled "GNU Free Documentation License".
|
104
src/KeePass.sln
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android", "keepass2android\keepass2android.csproj", "{A6CF8A86-37C1-4197-80FE-519DE2C842F5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = keepass2android\keepass2android.csproj
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$1.DirectoryNamespaceAssociation = None
|
||||
$1.ResourceNamePolicy = FileFormatDefault
|
||||
$0.TextStylePolicy = $2
|
||||
$2.FileWidth = 120
|
||||
$2.TabsToSpaces = False
|
||||
$2.inheritsSet = VisualStudio
|
||||
$2.inheritsScope = text/plain
|
||||
$2.scope = text/x-csharp
|
||||
$0.CSharpFormattingPolicy = $3
|
||||
$3.IndentSwitchBody = True
|
||||
$3.AnonymousMethodBraceStyle = NextLine
|
||||
$3.PropertyBraceStyle = NextLine
|
||||
$3.PropertyGetBraceStyle = NextLine
|
||||
$3.PropertySetBraceStyle = NextLine
|
||||
$3.EventBraceStyle = NextLine
|
||||
$3.EventAddBraceStyle = NextLine
|
||||
$3.EventRemoveBraceStyle = NextLine
|
||||
$3.StatementBraceStyle = NextLine
|
||||
$3.ArrayInitializerBraceStyle = NextLine
|
||||
$3.BeforeMethodDeclarationParentheses = False
|
||||
$3.BeforeMethodCallParentheses = False
|
||||
$3.BeforeConstructorDeclarationParentheses = False
|
||||
$3.BeforeDelegateDeclarationParentheses = False
|
||||
$3.NewParentheses = False
|
||||
$3.inheritsSet = Mono
|
||||
$3.inheritsScope = text/x-csharp
|
||||
$3.scope = text/x-csharp
|
||||
$0.TextStylePolicy = $4
|
||||
$4.FileWidth = 120
|
||||
$4.TabsToSpaces = False
|
||||
$4.inheritsSet = VisualStudio
|
||||
$4.inheritsScope = text/plain
|
||||
$4.scope = text/plain
|
||||
$0.TextStylePolicy = $5
|
||||
$5.inheritsSet = null
|
||||
$5.scope = application/xml
|
||||
$0.XmlFormattingPolicy = $6
|
||||
$6.inheritsSet = Mono
|
||||
$6.inheritsScope = application/xml
|
||||
$6.scope = application/xml
|
||||
$0.StandardHeader = $7
|
||||
$7.Text = @/*\nThis file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.\n\n Keepass2Android is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n Keepass2Android is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.\n */\n
|
||||
$7.IncludeInNewFiles = True
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -22,7 +24,6 @@ using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
using KeePassLib.Native;
|
||||
@ -137,13 +138,6 @@ namespace KeePassLib.Cryptography
|
||||
pb = TimeUtil.PackTime(DateTime.Now);
|
||||
ms.Write(pb, 0, pb.Length);
|
||||
|
||||
#if !KeePassLibSD
|
||||
Point pt = Cursor.Position;
|
||||
pb = MemUtil.UInt32ToBytes((uint)pt.X);
|
||||
ms.Write(pb, 0, pb.Length);
|
||||
pb = MemUtil.UInt32ToBytes((uint)pt.Y);
|
||||
ms.Write(pb, 0, pb.Length);
|
||||
#endif
|
||||
|
||||
pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
|
||||
ms.Write(pb, 0, pb.Length);
|
||||
|
@ -41,6 +41,8 @@
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="OpenTK-1.0" />
|
||||
<Reference Include="Mono.Security" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -71,7 +73,7 @@ namespace KeePassLib.Keys
|
||||
private void Construct(IOConnectionInfo iocFile)
|
||||
{
|
||||
byte[] pbFileData = IOConnection.ReadFile(iocFile);
|
||||
if(pbFileData == null) throw new FileNotFoundException();
|
||||
if(pbFileData == null) throw new Java.IO.FileNotFoundException();
|
||||
|
||||
byte[] pbKey = LoadXmlKeyFile(pbFileData);
|
||||
if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -59,18 +61,7 @@ namespace KeePassLib.Keys
|
||||
/// </summary>
|
||||
public KcpUserAccount()
|
||||
{
|
||||
// Test if ProtectedData is supported -- throws an exception
|
||||
// when running on an old system (Windows 98 / ME).
|
||||
byte[] pbDummyData = new byte[128];
|
||||
ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
||||
DataProtectionScope.CurrentUser);
|
||||
|
||||
byte[] pbKey = LoadUserKey(false);
|
||||
if(pbKey == null) pbKey = CreateUserKey();
|
||||
if(pbKey == null) throw new SecurityException(KLRes.UserAccountKeyError);
|
||||
|
||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||
Array.Clear(pbKey, 0, pbKey.Length);
|
||||
throw new NotSupportedException("DataProtection not supported on MonoForAndroid!");
|
||||
}
|
||||
|
||||
// public void Clear()
|
||||
@ -100,13 +91,7 @@ namespace KeePassLib.Keys
|
||||
#if !KeePassLibSD
|
||||
try
|
||||
{
|
||||
string strFilePath = GetUserKeyFilePath(false);
|
||||
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
||||
|
||||
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
||||
DataProtectionScope.CurrentUser);
|
||||
|
||||
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
||||
throw new NotSupportedException("DataProtection not supported on MonoForAndroid!");
|
||||
}
|
||||
catch(Exception exLoad)
|
||||
{
|
||||
@ -126,18 +111,7 @@ namespace KeePassLib.Keys
|
||||
#if !KeePassLibSD
|
||||
try
|
||||
{
|
||||
string strFilePath = GetUserKeyFilePath(true);
|
||||
|
||||
byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
|
||||
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
||||
m_pbEntropy, DataProtectionScope.CurrentUser);
|
||||
|
||||
File.WriteAllBytes(strFilePath, pbProtectedKey);
|
||||
|
||||
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
||||
Array.Clear(pbRandomKey, 0, pbRandomKey.Length);
|
||||
|
||||
pbKey = LoadUserKey(true);
|
||||
throw new NotSupportedException("DataProtection not supported on MonoForAndroid!");
|
||||
}
|
||||
catch(Exception) { pbKey = null; }
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -90,13 +92,14 @@ namespace KeePassLib.Native
|
||||
m_platID = Environment.OSVersion.Platform;
|
||||
|
||||
#if !KeePassLibSD
|
||||
// Mono returns PlatformID.Unix on Mac OS X, workaround this
|
||||
/*// Mono returns PlatformID.Unix on Mac OS X, workaround this
|
||||
//fails on Anroid
|
||||
if(m_platID.Value == PlatformID.Unix)
|
||||
{
|
||||
if((RunConsoleApp("uname", null) ?? string.Empty).Trim().Equals(
|
||||
"Darwin", StrUtil.CaseIgnoreCmp))
|
||||
m_platID = PlatformID.MacOSX;
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
return m_platID.Value;
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -24,8 +26,10 @@ using System.IO;
|
||||
|
||||
using KeePassLib.Utility;
|
||||
|
||||
|
||||
namespace KeePassLib
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Custom icon. <c>PwCustomIcon</c> objects are immutable.
|
||||
/// </summary>
|
||||
@ -33,7 +37,7 @@ namespace KeePassLib
|
||||
{
|
||||
private PwUuid m_pwUuid;
|
||||
private byte[] m_pbImageDataPng;
|
||||
private Image m_pCachedImage;
|
||||
private Android.Graphics.Bitmap m_pCachedImage;
|
||||
|
||||
public PwUuid Uuid
|
||||
{
|
||||
@ -45,7 +49,7 @@ namespace KeePassLib
|
||||
get { return m_pbImageDataPng; }
|
||||
}
|
||||
|
||||
public Image Image
|
||||
public Android.Graphics.Bitmap Image
|
||||
{
|
||||
get { return m_pCachedImage; }
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -1405,7 +1407,7 @@ namespace KeePassLib
|
||||
/// </summary>
|
||||
/// <param name="pwIconId">ID of the icon.</param>
|
||||
/// <returns>Image data.</returns>
|
||||
public Image GetCustomIcon(PwUuid pwIconId)
|
||||
public Android.Graphics.Bitmap GetCustomIcon(PwUuid pwIconId)
|
||||
{
|
||||
int nIndex = GetCustomIconIndex(pwIconId);
|
||||
|
||||
|
@ -40,5 +40,5 @@ public class R {
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
|
||||
to reference the layout/main.axml file, or R.strings.first_string to reference the first
|
||||
to reference the layout/main.axml file, or R.Strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
||||
|
@ -1,3 +1,4 @@
|
||||
#pragma warning disable 1591
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
@ -8,10 +9,13 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[assembly: Android.Runtime.ResourceDesignerAttribute("KeePassLib2Android.Resource", IsApplication=false)]
|
||||
|
||||
namespace KeePassLib2Android
|
||||
{
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("Novell.MonoDroid.Build.Tasks", "1.0.0.0")]
|
||||
public partial class Resource
|
||||
{
|
||||
|
||||
@ -27,7 +31,7 @@ namespace KeePassLib2Android
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7f020000
|
||||
public const int library_name = 2130837504;
|
||||
public static int library_name = 2130837504;
|
||||
|
||||
private String()
|
||||
{
|
||||
@ -35,3 +39,4 @@ namespace KeePassLib2Android
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -73,16 +75,8 @@ namespace KeePassLib.Security
|
||||
|
||||
static ProtectedBinary()
|
||||
{
|
||||
try // Test whether ProtectedMemory is supported
|
||||
{
|
||||
byte[] pbDummy = new byte[PmBlockSize * 2];
|
||||
ProtectedMemory.Protect(pbDummy, MemoryProtectionScope.SameProcess);
|
||||
m_bProtectionSupported = true;
|
||||
}
|
||||
catch(Exception) // Windows 98 / ME
|
||||
{
|
||||
m_bProtectionSupported = false;
|
||||
}
|
||||
//protection not supported on Android currently
|
||||
m_bProtectionSupported = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -143,7 +137,7 @@ namespace KeePassLib.Security
|
||||
|
||||
// Data size must be > 0, otherwise 'Protect' throws
|
||||
if(m_bProtected && m_bProtectionSupported && (m_uDataLen > 0))
|
||||
ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -164,9 +158,7 @@ namespace KeePassLib.Security
|
||||
{
|
||||
lock(m_objSync)
|
||||
{
|
||||
ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
|
||||
Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
|
||||
ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
else Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -137,7 +139,7 @@ namespace KeePassLib.Serialization
|
||||
if(!v[0].StartsWith(LockFileHeader)) { Debug.Assert(false); return null; }
|
||||
return new LockFileInfo(v[1], v[2], v[3], v[4], v[5]);
|
||||
}
|
||||
catch(FileNotFoundException) { }
|
||||
catch(Java.IO.FileNotFoundException) { }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
finally { if(s != null) s.Close(); }
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -92,7 +94,7 @@ namespace KeePassLib.Serialization
|
||||
bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);
|
||||
|
||||
#if !KeePassLibSD
|
||||
FileSecurity bkSecurity = null;
|
||||
|
||||
bool bEfsEncrypted = false;
|
||||
#endif
|
||||
|
||||
@ -107,7 +109,7 @@ namespace KeePassLib.Serialization
|
||||
bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
|
||||
|
||||
DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
|
||||
bkSecurity = File.GetAccessControl(m_iocBase.Path);
|
||||
|
||||
|
||||
File.SetCreationTime(m_iocTemp.Path, tCreation);
|
||||
}
|
||||
@ -131,8 +133,6 @@ namespace KeePassLib.Serialization
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
||||
if(bkSecurity != null)
|
||||
File.SetAccessControl(m_iocBase.Path, bkSecurity);
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -32,6 +34,44 @@ using KeePassLibSD;
|
||||
|
||||
namespace KeePassLib.Serialization
|
||||
{
|
||||
|
||||
[System.Serializable]
|
||||
public class InvalidDataException: Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:InvalidDataExceptionException"/> class
|
||||
/// </summary>
|
||||
public InvalidDataException ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:InvalidDataExceptionException"/> class
|
||||
/// </summary>
|
||||
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
|
||||
public InvalidDataException (string message) : base (message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:InvalidDataExceptionException"/> class
|
||||
/// </summary>
|
||||
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
|
||||
/// <param name="inner">The exception that is the cause of the current exception. </param>
|
||||
public InvalidDataException (string message, Exception inner) : base (message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:InvalidDataExceptionException"/> class
|
||||
/// </summary>
|
||||
/// <param name="context">The contextual information about the source or destination.</param>
|
||||
/// <param name="info">The object that holds the serialized object data.</param>
|
||||
protected InvalidDataException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class HashedBlockStream : Stream
|
||||
{
|
||||
private const int m_nDefaultBufferSize = 1024 * 1024; // 1 MB
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -243,6 +245,41 @@ namespace KeePassLib.Serialization
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
|
||||
class UploadOnCloseMemoryStream: MemoryStream
|
||||
{
|
||||
System.Net.WebClient webClient;
|
||||
string method;
|
||||
Uri destinationFilePath;
|
||||
|
||||
public UploadOnCloseMemoryStream(System.Net.WebClient _webClient, string _method, Uri _destinationFilePath)
|
||||
{
|
||||
this.webClient = _webClient;
|
||||
this.method = _method;
|
||||
this.destinationFilePath = _destinationFilePath;
|
||||
}
|
||||
|
||||
public UploadOnCloseMemoryStream(System.Net.WebClient _webClient, Uri _destinationFilePath)
|
||||
{
|
||||
this.webClient = _webClient;
|
||||
this.method = null;
|
||||
this.destinationFilePath = _destinationFilePath;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
if (method != null)
|
||||
{
|
||||
webClient.UploadData(destinationFilePath, method, this.ToArray());
|
||||
} else
|
||||
{
|
||||
webClient.UploadData(destinationFilePath, this.ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||
{
|
||||
if(ioc == null) { Debug.Assert(false); return null; }
|
||||
@ -256,9 +293,9 @@ namespace KeePassLib.Serialization
|
||||
if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
|
||||
StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
|
||||
StrUtil.CaseIgnoreCmp)))
|
||||
return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
|
||||
return new UploadOnCloseMemoryStream(CreateWebClient(ioc), WebRequestMethods.Http.Put, uri);
|
||||
|
||||
return CreateWebClient(ioc).OpenWrite(uri);
|
||||
return new UploadOnCloseMemoryStream(CreateWebClient(ioc), uri);
|
||||
}
|
||||
#else
|
||||
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||
@ -296,7 +333,7 @@ namespace KeePassLib.Serialization
|
||||
try
|
||||
{
|
||||
Stream s = OpenRead(ioc);
|
||||
if(s == null) throw new FileNotFoundException();
|
||||
if(s == null) throw new Java.IO.FileNotFoundException();
|
||||
|
||||
try { s.ReadByte(); }
|
||||
catch(Exception) { }
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -43,6 +45,49 @@ namespace KeePassLib.Serialization
|
||||
/// </summary>
|
||||
public sealed partial class KdbxFile
|
||||
{
|
||||
private class ColorTranslator
|
||||
{
|
||||
public static Color FromHtml(String colorString)
|
||||
{
|
||||
Color color;
|
||||
|
||||
if (colorString.StartsWith("#"))
|
||||
{
|
||||
colorString = colorString.Substring(1);
|
||||
}
|
||||
if (colorString.EndsWith(";"))
|
||||
{
|
||||
colorString = colorString.Substring(0, colorString.Length - 1);
|
||||
}
|
||||
|
||||
int red, green, blue;
|
||||
switch (colorString.Length)
|
||||
{
|
||||
case 6:
|
||||
red = int.Parse(colorString.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
|
||||
green = int.Parse(colorString.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
|
||||
blue = int.Parse(colorString.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
|
||||
color = Color.FromArgb(red, green, blue);
|
||||
break;
|
||||
case 3:
|
||||
red = int.Parse(colorString.Substring(0, 1), System.Globalization.NumberStyles.HexNumber);
|
||||
green = int.Parse(colorString.Substring(1, 1), System.Globalization.NumberStyles.HexNumber);
|
||||
blue = int.Parse(colorString.Substring(2, 1), System.Globalization.NumberStyles.HexNumber);
|
||||
color = Color.FromArgb(red, green, blue);
|
||||
break;
|
||||
case 1:
|
||||
red = green = blue = int.Parse(colorString.Substring(0, 1), System.Globalization.NumberStyles.HexNumber);
|
||||
color = Color.FromArgb(red, green, blue);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid color: " + colorString);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private enum KdbContext
|
||||
{
|
||||
Null,
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -27,7 +29,6 @@ using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
#if !KeePassLibSD
|
||||
using System.IO.Compression;
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -21,7 +23,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
using System.Globalization;
|
||||
@ -33,8 +34,12 @@ using KeePassLib.Utility;
|
||||
|
||||
namespace KeePassLib.Translation
|
||||
{
|
||||
public class Control
|
||||
{}
|
||||
|
||||
public sealed class KpccLayout
|
||||
{
|
||||
|
||||
public enum LayoutParameterEx
|
||||
{
|
||||
X, Y, Width, Height
|
||||
@ -113,7 +118,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
internal void ApplyTo(Control c)
|
||||
/*internal void ApplyTo(Control c)
|
||||
{
|
||||
Debug.Assert(c != null); if(c == null) return;
|
||||
|
||||
@ -181,7 +186,7 @@ namespace KeePassLib.Translation
|
||||
|
||||
Debug.Assert(false);
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
public static string ToControlRelativeString(string strEncoded)
|
||||
@ -268,7 +273,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
private static readonly Type[] m_vTextControls = new Type[] {
|
||||
/*private static readonly Type[] m_vTextControls = new Type[] {
|
||||
typeof(MenuStrip), typeof(PictureBox), typeof(ListView),
|
||||
typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser),
|
||||
typeof(Panel), typeof(StatusStrip), typeof(ProgressBar),
|
||||
@ -394,7 +399,7 @@ namespace KeePassLib.Translation
|
||||
|
||||
// Currently only v1: is supported, see HashControl
|
||||
return (m_strHash == strHash);
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -20,13 +22,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Serialization;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace KeePassLib.Translation
|
||||
{
|
||||
public class Form
|
||||
{}
|
||||
public sealed class KPFormCustomization
|
||||
{
|
||||
private string m_strFQName = string.Empty;
|
||||
@ -75,7 +78,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
public void ApplyTo(Form form)
|
||||
/*public void ApplyTo(Form form)
|
||||
{
|
||||
Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form");
|
||||
|
||||
@ -100,7 +103,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
foreach(Control cSub in c.Controls) ApplyToControl(cSub);
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -21,11 +23,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace KeePassLib.Translation
|
||||
{
|
||||
public class ToolStripItemCollection
|
||||
{}
|
||||
public sealed class KPStringTable
|
||||
{
|
||||
private string m_strName = string.Empty;
|
||||
@ -67,7 +71,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
public void ApplyTo(ToolStripItemCollection tsic)
|
||||
/*public void ApplyTo(ToolStripItemCollection tsic)
|
||||
{
|
||||
if(tsic == null) throw new ArgumentNullException("tsic");
|
||||
|
||||
@ -93,7 +97,7 @@ namespace KeePassLib.Translation
|
||||
if((tsmi != null) && (tsmi.DropDownItems != null))
|
||||
this.ApplyTo(tsmi.DropDownItems);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -23,7 +25,7 @@ using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
@ -154,7 +156,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
public void ApplyTo(Form form)
|
||||
/*public void ApplyTo(Form form)
|
||||
{
|
||||
if(form == null) throw new ArgumentNullException("form");
|
||||
|
||||
@ -183,8 +185,8 @@ namespace KeePassLib.Translation
|
||||
try { RtlApplyToControls(form.Controls); }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
/*
|
||||
private static void RtlApplyToControls(Control.ControlCollection cc)
|
||||
{
|
||||
foreach(Control c in cc)
|
||||
@ -210,9 +212,9 @@ namespace KeePassLib.Translation
|
||||
|
||||
if((c is GroupBox) || (c is Panel)) RtlMoveChildControls(c);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
private static void RtlMoveChildControls(Control cParent)
|
||||
/*private static void RtlMoveChildControls(Control cParent)
|
||||
{
|
||||
int nParentWidth = cParent.Size.Width;
|
||||
|
||||
@ -246,7 +248,7 @@ namespace KeePassLib.Translation
|
||||
}
|
||||
|
||||
if(kpst != null) kpst.ApplyTo(tsic);
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -22,14 +24,15 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
using System.Diagnostics;
|
||||
using Android.Graphics;
|
||||
|
||||
namespace KeePassLib.Utility
|
||||
{
|
||||
public static class GfxUtil
|
||||
{
|
||||
public static Image LoadImage(byte[] pb)
|
||||
public static Android.Graphics.Bitmap LoadImage(byte[] pb)
|
||||
{
|
||||
if(pb == null) throw new ArgumentNullException("pb");
|
||||
|
||||
@ -37,59 +40,43 @@ namespace KeePassLib.Utility
|
||||
try { return LoadImagePriv(ms); }
|
||||
catch(Exception)
|
||||
{
|
||||
Image imgIco = TryLoadIco(pb);
|
||||
Android.Graphics.Bitmap imgIco = TryLoadIco(pb);
|
||||
if(imgIco != null) return imgIco;
|
||||
throw;
|
||||
}
|
||||
finally { ms.Close(); }
|
||||
}
|
||||
|
||||
private static Image LoadImagePriv(Stream s)
|
||||
private static Android.Graphics.Bitmap LoadImagePriv(Stream s)
|
||||
{
|
||||
// Image.FromStream wants the stream to be open during
|
||||
// the whole lifetime of the image; as we can't guarantee
|
||||
// this, we make a copy of the image
|
||||
Image imgSrc = null;
|
||||
try
|
||||
{
|
||||
#if !KeePassLibSD
|
||||
imgSrc = Image.FromStream(s);
|
||||
Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height,
|
||||
PixelFormat.Format32bppArgb);
|
||||
Android.Graphics.Bitmap img = null;
|
||||
|
||||
#if !KeePassLibSD
|
||||
|
||||
img = BitmapFactory.DecodeStream(s);
|
||||
|
||||
try
|
||||
{
|
||||
bmp.SetResolution(imgSrc.HorizontalResolution,
|
||||
imgSrc.VerticalResolution);
|
||||
Debug.Assert(bmp.Size == imgSrc.Size);
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
#else
|
||||
imgSrc = new Bitmap(s);
|
||||
Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height);
|
||||
#endif
|
||||
|
||||
using(Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.Clear(Color.Transparent);
|
||||
g.DrawImage(imgSrc, 0, 0);
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
finally { if(imgSrc != null) imgSrc.Dispose(); }
|
||||
return img;
|
||||
|
||||
}
|
||||
|
||||
private static Image TryLoadIco(byte[] pb)
|
||||
private static Android.Graphics.Bitmap TryLoadIco(byte[] pb)
|
||||
{
|
||||
#if !KeePassLibSD
|
||||
throw new NotImplementedException();
|
||||
/*
|
||||
MemoryStream ms = new MemoryStream(pb, false);
|
||||
try { return (new Icon(ms)).ToBitmap(); }
|
||||
catch(Exception) { }
|
||||
finally { ms.Close(); }
|
||||
finally { ms.Close(); }*/
|
||||
#endif
|
||||
|
||||
return null;
|
||||
//return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -21,7 +23,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using KeePassLib.Resources;
|
||||
@ -29,17 +31,36 @@ using KeePassLib.Serialization;
|
||||
|
||||
namespace KeePassLib.Utility
|
||||
{
|
||||
public enum MessageBoxButtons
|
||||
{
|
||||
OK, OKCancel, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel
|
||||
}
|
||||
public enum MessageBoxIcon
|
||||
{
|
||||
Information, Warning, Error, Question
|
||||
}
|
||||
public enum MessageBoxDefaultButton
|
||||
{
|
||||
Button1, Button2, Button3
|
||||
}
|
||||
|
||||
public enum DialogResult
|
||||
{
|
||||
Yes, No, Cancel, Retry, Abort
|
||||
}
|
||||
|
||||
|
||||
public sealed class MessageServiceEventArgs : EventArgs
|
||||
{
|
||||
private string m_strTitle = string.Empty;
|
||||
private string m_strText = string.Empty;
|
||||
private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK;
|
||||
private MessageBoxIcon m_msgIcon = MessageBoxIcon.None;
|
||||
//private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK;
|
||||
//private MessageBoxIcon m_msgIcon = MessageBoxIcon.None;
|
||||
|
||||
public string Title { get { return m_strTitle; } }
|
||||
public string Text { get { return m_strText; } }
|
||||
public MessageBoxButtons Buttons { get { return m_msgButtons; } }
|
||||
public MessageBoxIcon Icon { get { return m_msgIcon; } }
|
||||
//public MessageBoxButtons Buttons { get { return m_msgButtons; } }
|
||||
//public MessageBoxIcon Icon { get { return m_msgIcon; } }
|
||||
|
||||
public MessageServiceEventArgs() { }
|
||||
|
||||
@ -48,8 +69,7 @@ namespace KeePassLib.Utility
|
||||
{
|
||||
m_strTitle = (strTitle ?? string.Empty);
|
||||
m_strText = (strText ?? string.Empty);
|
||||
m_msgButtons = msgButtons;
|
||||
m_msgIcon = msgIcon;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,14 +82,12 @@ namespace KeePassLib.Utility
|
||||
private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Warning;
|
||||
private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Error;
|
||||
|
||||
private const MessageBoxOptions m_mboRtl = (MessageBoxOptions.RtlReading |
|
||||
MessageBoxOptions.RightAlign);
|
||||
#else
|
||||
private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Asterisk;
|
||||
private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Exclamation;
|
||||
private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Hand;
|
||||
#endif
|
||||
private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question;
|
||||
//private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question;
|
||||
|
||||
public static string NewLine
|
||||
{
|
||||
@ -159,13 +177,13 @@ namespace KeePassLib.Utility
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
internal static Form GetTopForm()
|
||||
/*internal static Form GetTopForm()
|
||||
{
|
||||
FormCollection fc = Application.OpenForms;
|
||||
if((fc == null) || (fc.Count == 0)) return null;
|
||||
|
||||
return fc[fc.Count - 1];
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
private static DialogResult SafeShowMessageBox(string strText, string strTitle,
|
||||
@ -174,7 +192,14 @@ namespace KeePassLib.Utility
|
||||
#if KeePassLibSD
|
||||
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
|
||||
#else
|
||||
IWin32Window wnd = null;
|
||||
|
||||
if (mb == MessageBoxButtons.OK)
|
||||
{
|
||||
//Android.Widget.Toast toast = ..
|
||||
}
|
||||
//this might help: http://www.gregshackles.com/2011/04/using-background-threads-in-mono-for-android-applications/
|
||||
throw new NotImplementedException();
|
||||
/*IWin32Window wnd = null;
|
||||
try
|
||||
{
|
||||
Form f = GetTopForm();
|
||||
@ -203,11 +228,12 @@ namespace KeePassLib.Utility
|
||||
if(StrUtil.RightToLeft)
|
||||
return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl);
|
||||
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !KeePassLibSD
|
||||
internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
|
||||
/* internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
|
||||
string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
|
||||
MessageBoxDefaultButton mdb);
|
||||
|
||||
@ -218,7 +244,7 @@ namespace KeePassLib.Utility
|
||||
if(StrUtil.RightToLeft)
|
||||
return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb, m_mboRtl);
|
||||
return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb);
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
public static void ShowInfo(params object[] vLines)
|
||||
@ -284,8 +310,9 @@ namespace KeePassLib.Utility
|
||||
try
|
||||
{
|
||||
#if !KeePassLibSD
|
||||
Clipboard.Clear();
|
||||
Clipboard.SetText(ObjectsToMessage(vLines, true));
|
||||
/* nicht benoetigt - hoffentlich :-)
|
||||
Clipboard.Clear();
|
||||
Clipboard.SetText(ObjectsToMessage(vLines, true));*/
|
||||
#else
|
||||
Clipboard.SetDataObject(ObjectsToMessage(vLines, true));
|
||||
#endif
|
||||
@ -312,10 +339,10 @@ namespace KeePassLib.Utility
|
||||
|
||||
if(MessageService.MessageShowing != null)
|
||||
MessageService.MessageShowing(null, new MessageServiceEventArgs(
|
||||
strTitleEx, strTextEx, mbb, m_mbiQuestion));
|
||||
strTitleEx, strTextEx, mbb, MessageBoxIcon.Question));
|
||||
|
||||
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, mbb,
|
||||
m_mbiQuestion, MessageBoxDefaultButton.Button1);
|
||||
MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
|
||||
|
||||
--m_uCurrentMessageCount;
|
||||
return dr;
|
||||
@ -330,10 +357,10 @@ namespace KeePassLib.Utility
|
||||
|
||||
if(MessageService.MessageShowing != null)
|
||||
MessageService.MessageShowing(null, new MessageServiceEventArgs(
|
||||
strTitleEx, strTextEx, MessageBoxButtons.YesNo, m_mbiQuestion));
|
||||
strTitleEx, strTextEx, MessageBoxButtons.YesNo, MessageBoxIcon.Question));
|
||||
|
||||
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx,
|
||||
MessageBoxButtons.YesNo, m_mbiQuestion, bDefaultToYes ?
|
||||
MessageBoxButtons.YesNo, MessageBoxIcon.Question, bDefaultToYes ?
|
||||
MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2);
|
||||
|
||||
--m_uCurrentMessageCount;
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
|
||||
|
||||
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
|
||||
@ -990,15 +992,7 @@ namespace KeePassLib.Utility
|
||||
|
||||
try
|
||||
{
|
||||
byte[] pbPlain = StrUtil.Utf8.GetBytes(strPlainText);
|
||||
byte[] pbEnc = ProtectedData.Protect(pbPlain, m_pbOptEnt,
|
||||
DataProtectionScope.CurrentUser);
|
||||
|
||||
#if !KeePassLibSD
|
||||
return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None);
|
||||
#else
|
||||
return Convert.ToBase64String(pbEnc);
|
||||
#endif
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
@ -1012,10 +1006,8 @@ namespace KeePassLib.Utility
|
||||
try
|
||||
{
|
||||
byte[] pbEnc = Convert.FromBase64String(strCipherText);
|
||||
byte[] pbPlain = ProtectedData.Unprotect(pbEnc, m_pbOptEnt,
|
||||
DataProtectionScope.CurrentUser);
|
||||
throw new NotSupportedException();
|
||||
|
||||
return StrUtil.Utf8.GetString(pbPlain, 0, pbPlain.Length);
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
|
72
src/keepass2android/AboutDialog.cs
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Content.PM;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class AboutDialog : Dialog {
|
||||
|
||||
public AboutDialog(Context context):base (context) {
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState) {
|
||||
base.OnCreate(savedInstanceState);
|
||||
SetContentView(Resource.Layout.about);
|
||||
SetTitle(Resource.String.app_name);
|
||||
|
||||
setVersion();
|
||||
|
||||
Button okButton = (Button) FindViewById(Resource.Id.about_button);
|
||||
okButton.Click += (object sender, EventArgs e) => {
|
||||
Dismiss();
|
||||
};
|
||||
}
|
||||
|
||||
private void setVersion() {
|
||||
Context ctx = Context;
|
||||
|
||||
String version;
|
||||
try {
|
||||
PackageInfo packageInfo = ctx.PackageManager.GetPackageInfo(ctx.PackageName, 0);
|
||||
version = packageInfo.VersionName;
|
||||
|
||||
} catch (PackageManager.NameNotFoundException) {
|
||||
version = "";
|
||||
}
|
||||
|
||||
TextView tv = (TextView) FindViewById(Resource.Id.version);
|
||||
tv.Text = version;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
20
src/keepass2android/AssemblyInfo.cs
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using Android.App;
|
||||
|
||||
|
||||
|
45
src/keepass2android/BitmapDrawableCompat.cs
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class BitmapDrawableCompat {
|
||||
|
||||
public static BitmapDrawable getBitmapDrawable(Resources res, Bitmap bitmap) {
|
||||
return new BitmapDrawable(res, bitmap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
52
src/keepass2android/CancelDialog.cs
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class CancelDialog : Dialog {
|
||||
|
||||
private bool mCanceled = false;
|
||||
|
||||
public CancelDialog(Context context): base(context) {
|
||||
}
|
||||
|
||||
public bool canceled() {
|
||||
return mCanceled;
|
||||
}
|
||||
|
||||
|
||||
public override void Cancel() {
|
||||
base.Cancel();
|
||||
mCanceled = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
244
src/keepass2android/Database.cs
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class Database {
|
||||
|
||||
|
||||
public Dictionary<PwUuid, PwGroup> groups = new Dictionary<PwUuid, PwGroup>(new PwUuidEqualityComparer());
|
||||
public Dictionary<PwUuid, PwEntry> entries = new Dictionary<PwUuid, PwEntry>(new PwUuidEqualityComparer());
|
||||
public HashSet<PwGroup> dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
|
||||
public PwGroup root;
|
||||
public PwDatabase pm;
|
||||
public IOConnectionInfo mIoc;
|
||||
public SearchDbHelper searchHelper;
|
||||
|
||||
public DrawableFactory drawFactory = new DrawableFactory();
|
||||
|
||||
private bool loaded = false;
|
||||
|
||||
|
||||
public bool Loaded {
|
||||
get { return loaded;}
|
||||
set { loaded = value; }
|
||||
}
|
||||
|
||||
public bool Open
|
||||
{
|
||||
get { return Loaded && (!Locked); }
|
||||
}
|
||||
|
||||
bool locked;
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return locked;
|
||||
}
|
||||
set
|
||||
{
|
||||
locked = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void LoadData (Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status)
|
||||
{
|
||||
mIoc = iocInfo;
|
||||
|
||||
KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase ();
|
||||
|
||||
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey ();
|
||||
key.AddUserKey (new KeePassLib.Keys.KcpPassword (password));
|
||||
if (!String.IsNullOrEmpty (keyfile)) {
|
||||
|
||||
try { key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile)); }
|
||||
catch(Exception)
|
||||
{
|
||||
throw new KeyFileException();
|
||||
}
|
||||
}
|
||||
|
||||
pwDatabase.Open(iocInfo, key, status);
|
||||
|
||||
root = pwDatabase.RootGroup;
|
||||
populateGlobals(root);
|
||||
|
||||
|
||||
Loaded = true;
|
||||
pm = pwDatabase;
|
||||
searchHelper = new SearchDbHelper(ctx);
|
||||
}
|
||||
|
||||
bool quickUnlockEnabled = false;
|
||||
public bool QuickUnlockEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return quickUnlockEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
quickUnlockEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
//KeyLength of QuickUnlock at time of loading the database.
|
||||
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
|
||||
public int QuickUnlockKeyLength
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public PwGroup SearchForText(String str) {
|
||||
PwGroup group = searchHelper.searchForText(this, str);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup Search(SearchParameters searchParams)
|
||||
{
|
||||
return searchHelper.search(this, searchParams);
|
||||
}
|
||||
|
||||
|
||||
public PwGroup SearchForExactUrl(String url) {
|
||||
PwGroup group = searchHelper.searchForExactUrl(this, url);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup SearchForHost(String url) {
|
||||
PwGroup group = searchHelper.searchForHost(this, url);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void SaveData(Context ctx) {
|
||||
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(ctx);
|
||||
pm.UseFileTransactions = prefs.GetBoolean(ctx.GetString(Resource.String.UseFileTransactions_key), true);
|
||||
pm.Save(null);
|
||||
|
||||
}
|
||||
class SaveStatusLogger: IStatusLogger
|
||||
{
|
||||
#region IStatusLogger implementation
|
||||
public void StartLogging (string strOperation, bool bWriteOperationToLog)
|
||||
{
|
||||
}
|
||||
public void EndLogging ()
|
||||
{
|
||||
}
|
||||
public bool SetProgress (uint uPercent)
|
||||
{
|
||||
Android.Util.Log.Debug("DEBUG", "Progress: " + uPercent+"%");
|
||||
return true;
|
||||
}
|
||||
public bool SetText (string strNewText, LogStatusType lsType)
|
||||
{
|
||||
Android.Util.Log.Debug("DEBUG", strNewText);
|
||||
return true;
|
||||
}
|
||||
public bool ContinueWork ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private void populateGlobals (PwGroup currentGroup)
|
||||
{
|
||||
|
||||
var childGroups = currentGroup.Groups;
|
||||
var childEntries = currentGroup.Entries;
|
||||
|
||||
foreach (PwEntry e in childEntries) {
|
||||
entries [e.Uuid] = e;
|
||||
}
|
||||
foreach (PwGroup g in childGroups) {
|
||||
groups[g.Uuid] = g;
|
||||
populateGlobals(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
groups.Clear();
|
||||
entries.Clear();
|
||||
dirty.Clear();
|
||||
drawFactory.Clear();
|
||||
|
||||
root = null;
|
||||
pm = null;
|
||||
mIoc = null;
|
||||
loaded = false;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
public void markAllGroupsAsDirty() {
|
||||
foreach ( PwGroup group in groups.Values ) {
|
||||
dirty.Add(group);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
public void LoadData (Context mCtx, string mFileName, string mPass, string mKey, UpdateStatus mStatus)
|
||||
{
|
||||
KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase();
|
||||
KeePassLib.Serialization.IOConnectionInfo iocInfo = KeePassLib.Serialization.IOConnectionInfo.FromPath("/sdcard/keepass2androidtest.kdbx");
|
||||
KeePassLib.Serialization.IOConnectionInfo iocInfoSave = KeePassLib.Serialization.IOConnectionInfo.FromPath("/sdcard/keepass2androidtestSaved.kdbx");
|
||||
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey();
|
||||
key.AddUserKey(new KeePassLib.Keys.KcpPassword("test"));
|
||||
|
||||
pwDatabase.Open(iocInfo, key, new LogToButton(this));
|
||||
pwDatabase.RootGroup.AddGroup(new KeePassLib.PwGroup(true, true, "generatedFromKp2ANeu", KeePassLib.PwIcon.Folder), true);
|
||||
pwDatabase.SaveAs(iocInfoSave,false,new LogToButton(this));
|
||||
pwDatabase.Close();
|
||||
//KeePassLib.Serialization.KdbxFile f = new KeePassLib.Serialization.KdbxFile(pwDatabase);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
519
src/keepass2android/EntryActivity.cs
Normal file
@ -0,0 +1,519 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
using Android.Text.Format;
|
||||
using KeePassLib.Utility;
|
||||
using Java.Util;
|
||||
using Android.Preferences;
|
||||
using Android.Text.Method;
|
||||
using Android.Util;
|
||||
using System.Globalization;
|
||||
using Android.Content.PM;
|
||||
using KeePassLib.Security;
|
||||
using keepass2android.view;
|
||||
using Android.Webkit;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
||||
public class EntryActivity : LockCloseActivity {
|
||||
public const String KEY_ENTRY = "entry";
|
||||
public const String KEY_REFRESH_POS = "refresh_pos";
|
||||
public const String KEY_CLOSE_AFTER_CREATE = "close_after_create";
|
||||
|
||||
public static void Launch(Activity act, PwEntry pw, int pos) {
|
||||
Launch(act, pw, pos, false);
|
||||
}
|
||||
|
||||
public static void Launch(Activity act, PwEntry pw, int pos, bool closeAfterCreate) {
|
||||
Intent i;
|
||||
|
||||
i = new Intent(act, typeof(EntryActivity));
|
||||
|
||||
|
||||
i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString());
|
||||
i.PutExtra(KEY_REFRESH_POS, pos);
|
||||
i.PutExtra(KEY_CLOSE_AFTER_CREATE, closeAfterCreate);
|
||||
|
||||
act.StartActivityForResult(i,0);
|
||||
}
|
||||
|
||||
protected PwEntry mEntry;
|
||||
|
||||
private bool mShowPassword;
|
||||
private int mPos;
|
||||
|
||||
|
||||
|
||||
protected void setEntryView() {
|
||||
SetContentView(Resource.Layout.entry_view);
|
||||
}
|
||||
|
||||
protected void setupEditButtons() {
|
||||
Button edit = (Button) FindViewById(Resource.Id.entry_edit);
|
||||
edit.Click += (sender, e) => {
|
||||
EntryEditActivity.Launch(this, mEntry);
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
setEntryView();
|
||||
|
||||
Context appCtx = ApplicationContext;
|
||||
|
||||
|
||||
Database db = App.getDB();
|
||||
// Likely the app has been killed exit the activity
|
||||
if (! db.Loaded)
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
SetResult(KeePass.EXIT_NORMAL);
|
||||
|
||||
Intent i = Intent;
|
||||
PwUuid uuid = new PwUuid(MemUtil.HexStringToByteArray(i.GetStringExtra(KEY_ENTRY)));
|
||||
mPos = i.GetIntExtra(KEY_REFRESH_POS, -1);
|
||||
|
||||
bool closeAfterCreate = i.GetBooleanExtra(KEY_CLOSE_AFTER_CREATE, false);
|
||||
|
||||
mEntry = db.entries [uuid];
|
||||
|
||||
|
||||
|
||||
// Refresh Menu contents in case onCreateMenuOptions was called before mEntry was set
|
||||
ActivityCompat.invalidateOptionsMenu(this);
|
||||
|
||||
// Update last access time.
|
||||
mEntry.Touch(false);
|
||||
|
||||
if (PwDefs.IsTanEntry(mEntry) && prefs.GetBoolean(GetString(Resource.String.TanExpiresOnUse_key), Resources.GetBoolean(Resource.Boolean.TanExpiresOnUse_default)) && ((mEntry.Expires == false) || mEntry.ExpiryTime > DateTime.Now))
|
||||
{
|
||||
PwEntry backupEntry = mEntry.CloneDeep();
|
||||
mEntry.ExpiryTime = DateTime.Now;
|
||||
mEntry.Expires = true;
|
||||
mEntry.Touch(true);
|
||||
requiresRefresh();
|
||||
Handler handler = new Handler();
|
||||
UpdateEntry update = new UpdateEntry(this, App.getDB(), backupEntry, mEntry, new AfterSave(handler));
|
||||
ProgressTask pt = new ProgressTask(this, update, Resource.String.saving_database);
|
||||
pt.run();
|
||||
}
|
||||
fillData(false);
|
||||
|
||||
setupEditButtons();
|
||||
|
||||
Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService));
|
||||
Intent.SetAction(Intents.SHOW_NOTIFICATION);
|
||||
showNotIntent.PutExtra(KEY_ENTRY, mEntry.Uuid.ToHexString());
|
||||
|
||||
StartService(showNotIntent);
|
||||
|
||||
Android.Util.Log.Debug("DEBUG", "Requesting copy to clipboard for Uuid=" + mEntry.Uuid.ToHexString());
|
||||
|
||||
/*foreach (PwUuid key in App.getDB().entries.Keys)
|
||||
{
|
||||
Android.Util.Log.Debug("DEBUG",key.ToHexString() + " -> " + App.getDB().entries[key].Uuid.ToHexString());
|
||||
}*/
|
||||
|
||||
if (closeAfterCreate)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterSave : OnFinish {
|
||||
|
||||
public AfterSave(Handler handler):base(handler) {
|
||||
|
||||
}
|
||||
|
||||
public override void run() {
|
||||
|
||||
base.run();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
private String getDateTime(System.DateTime dt) {
|
||||
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
||||
}
|
||||
|
||||
String concatTags(List<string> tags)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (string tag in tags)
|
||||
{
|
||||
sb.Append(tag);
|
||||
sb.Append(", ");
|
||||
}
|
||||
if (tags.Count > 0)
|
||||
sb.Remove(sb.Length-2,2);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
void populateExtraStrings(bool trimList)
|
||||
{
|
||||
ViewGroup extraGroup = (ViewGroup)FindViewById(Resource.Id.extra_strings);
|
||||
if (trimList)
|
||||
{
|
||||
extraGroup.RemoveAllViews();
|
||||
}
|
||||
bool hasExtraFields = false;
|
||||
foreach (KeyValuePair<string, ProtectedString> pair in mEntry.Strings)
|
||||
{
|
||||
String key = pair.Key;
|
||||
if (!PwDefs.IsStandardField(key))
|
||||
{
|
||||
View view = new EntrySection(this, null, key, pair.Value.ReadString());
|
||||
extraGroup.AddView(view);
|
||||
hasExtraFields = true;
|
||||
}
|
||||
}
|
||||
FindViewById(Resource.Id.entry_extra_strings_label).Visibility = hasExtraFields ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
string writeBinaryToFile(string key)
|
||||
{
|
||||
ProtectedBinary pb = mEntry.Binaries.Get(key);
|
||||
System.Diagnostics.Debug.Assert(pb != null); if(pb == null) throw new ArgumentException();
|
||||
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
string binaryDirectory = prefs.GetString(GetString(Resource.String.BinaryDirectory_key),GetString(Resource.String.BinaryDirectory_default));
|
||||
|
||||
var targetFile = new Java.IO.File(binaryDirectory,key);
|
||||
|
||||
Java.IO.File parent = targetFile.ParentFile;
|
||||
|
||||
if (parent == null || (parent.Exists() && ! parent.IsDirectory))
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_invalid_path,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! parent.Exists())
|
||||
{
|
||||
// Create parent dircetory
|
||||
if (! parent.Mkdirs())
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_could_not_create_parent,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
string filename = targetFile.AbsolutePath;
|
||||
|
||||
byte[] pbData = pb.ReadData();
|
||||
try { System.IO.File.WriteAllBytes(filename, pbData); }
|
||||
catch(Exception exWrite)
|
||||
{
|
||||
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_Failed, new Java.Lang.Object[]{ filename})
|
||||
+exWrite.Message,ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
MemUtil.ZeroByteArray(pbData);
|
||||
}
|
||||
|
||||
return filename;
|
||||
|
||||
}
|
||||
|
||||
void openBinaryFile(string filename)
|
||||
{
|
||||
String theMIMEType = getMimeType(filename);
|
||||
if (theMIMEType != null)
|
||||
{
|
||||
Intent theIntent = new Intent(Intent.ActionView);
|
||||
theIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
||||
theIntent.SetDataAndType(Android.Net.Uri.FromFile(new Java.IO.File(filename)), theMIMEType);
|
||||
try
|
||||
{
|
||||
StartActivity(theIntent);
|
||||
}
|
||||
catch (ActivityNotFoundException anfe)
|
||||
{
|
||||
//ignore
|
||||
Toast.MakeText(this, "Couldn't open file", ToastLength.Short).Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void populateBinaries(bool trimList)
|
||||
{
|
||||
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
||||
if (trimList)
|
||||
{
|
||||
binariesGroup.RemoveAllViews();
|
||||
}
|
||||
foreach (KeyValuePair<string, ProtectedBinary> pair in mEntry.Binaries)
|
||||
{
|
||||
String key = pair.Key;
|
||||
Button binaryButton = new Button(this);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent);
|
||||
binaryButton.Text = key;
|
||||
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuSave),null, null, null);
|
||||
binaryButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
Button btnSender = (Button)(sender);
|
||||
string newFilename = writeBinaryToFile(btnSender.Text);
|
||||
|
||||
if (newFilename != null)
|
||||
{
|
||||
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[]{newFilename}), ToastLength.Short).Show();
|
||||
openBinaryFile(newFilename);
|
||||
}
|
||||
|
||||
};
|
||||
binariesGroup.AddView(binaryButton,layoutParams);
|
||||
|
||||
|
||||
}
|
||||
FindViewById(Resource.Id.entry_binaries_label).Visibility = mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
// url = file path or whatever suitable URL you want.
|
||||
public static String getMimeType(String url)
|
||||
{
|
||||
String type = null;
|
||||
String extension = MimeTypeMap.GetFileExtensionFromUrl(url);
|
||||
if (extension != null) {
|
||||
MimeTypeMap mime = MimeTypeMap.Singleton;
|
||||
type = mime.GetMimeTypeFromExtension(extension);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
protected void fillData(bool trimList)
|
||||
{
|
||||
ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon);
|
||||
App.getDB().drawFactory.assignDrawableTo(iv, Resources, App.getDB().pm, mEntry.IconId, mEntry.CustomIconUuid);
|
||||
|
||||
//populateText(Resource.Id.entry_title, mEntry.Strings.ReadSafe(PwDefs.TitleField));
|
||||
var button = ((Button)FindViewById(Resource.Id.entry_title));
|
||||
button.Text = mEntry.Strings.ReadSafe(PwDefs.TitleField);
|
||||
button.Click += (object sender, EventArgs e) => {
|
||||
Finish(); };
|
||||
|
||||
populateText(Resource.Id.entry_user_name, Resource.Id.entry_user_name_label, mEntry.Strings.ReadSafe(PwDefs.UserNameField));
|
||||
|
||||
populateText(Resource.Id.entry_url, Resource.Id.entry_url_label, mEntry.Strings.ReadSafe(PwDefs.UrlField));
|
||||
populateText(Resource.Id.entry_password, Resource.Id.entry_password_label, mEntry.Strings.ReadSafe(PwDefs.PasswordField));
|
||||
setPasswordStyle();
|
||||
|
||||
populateText(Resource.Id.entry_created, Resource.Id.entry_created_label, getDateTime(mEntry.CreationTime));
|
||||
populateText(Resource.Id.entry_modified, Resource.Id.entry_modified_label, getDateTime(mEntry.LastModificationTime));
|
||||
populateText(Resource.Id.entry_accessed, Resource.Id.entry_accessed_label, getDateTime(mEntry.LastAccessTime));
|
||||
|
||||
if (mEntry.Expires)
|
||||
{
|
||||
populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, getDateTime(mEntry.ExpiryTime));
|
||||
} else
|
||||
{
|
||||
populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, Resource.String.never);
|
||||
}
|
||||
populateText(Resource.Id.entry_comment, Resource.Id.entry_comment_label, mEntry.Strings.ReadSafe(PwDefs.NotesField));
|
||||
|
||||
populateText(Resource.Id.entry_tags, Resource.Id.entry_tags_label, concatTags(mEntry.Tags));
|
||||
|
||||
populateText(Resource.Id.entry_override_url, Resource.Id.entry_override_url_label, mEntry.OverrideUrl);
|
||||
|
||||
populateExtraStrings(trimList);
|
||||
|
||||
populateBinaries(trimList);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void populateText(int viewId, int headerViewId,int resId) {
|
||||
View header = FindViewById(headerViewId);
|
||||
TextView tv = (TextView)FindViewById(viewId);
|
||||
|
||||
header.Visibility = tv.Visibility = ViewStates.Visible;
|
||||
tv.SetText (resId);
|
||||
}
|
||||
|
||||
private void populateText(int viewId, int headerViewId, String text)
|
||||
{
|
||||
View header = FindViewById(headerViewId);
|
||||
TextView tv = (TextView)FindViewById(viewId);
|
||||
if (String.IsNullOrEmpty(text))
|
||||
{
|
||||
header.Visibility = tv.Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
header.Visibility = tv.Visibility = ViewStates.Visible;
|
||||
tv.Text = text;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void requiresRefresh ()
|
||||
{
|
||||
Intent ret = new Intent ();
|
||||
ret.PutExtra (KEY_REFRESH_POS, mPos);
|
||||
SetResult (KeePass.EXIT_REFRESH, ret);
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
if ( resultCode == KeePass.EXIT_REFRESH || resultCode == KeePass.EXIT_REFRESH_TITLE ) {
|
||||
fillData(true);
|
||||
if ( resultCode == KeePass.EXIT_REFRESH_TITLE ) {
|
||||
requiresRefresh ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
MenuInflater inflater = MenuInflater;
|
||||
inflater.Inflate(Resource.Menu.entry, menu);
|
||||
|
||||
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||
if ( mShowPassword ) {
|
||||
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
||||
} else {
|
||||
togglePassword.SetTitle(Resource.String.show_password);
|
||||
}
|
||||
|
||||
IMenuItem gotoUrl = menu.FindItem(Resource.Id.menu_goto_url);
|
||||
//Disabled IMenuItem copyUser = menu.FindItem(Resource.Id.menu_copy_user);
|
||||
//Disabled IMenuItem copyPass = menu.FindItem(Resource.Id.menu_copy_pass);
|
||||
|
||||
// In API >= 11 onCreateOptionsMenu may be called before onCreate completes
|
||||
// so mEntry may not be set
|
||||
if (mEntry == null) {
|
||||
gotoUrl.SetVisible(false);
|
||||
//Disabled copyUser.SetVisible(false);
|
||||
//Disabled copyPass.SetVisible(false);
|
||||
}
|
||||
else {
|
||||
String url = mEntry.Strings.ReadSafe (PwDefs.UrlField);
|
||||
if (String.IsNullOrEmpty(url)) {
|
||||
// disable button if url is not available
|
||||
gotoUrl.SetVisible(false);
|
||||
}
|
||||
if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.UserNameField ))) {
|
||||
// disable button if username is not available
|
||||
//Disabled copyUser.SetVisible(false);
|
||||
}
|
||||
if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.PasswordField ))) {
|
||||
// disable button if password is not available
|
||||
//Disabled copyPass.SetVisible(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setPasswordStyle() {
|
||||
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
||||
|
||||
if ( mShowPassword ) {
|
||||
password.TransformationMethod = null;
|
||||
} else {
|
||||
password.TransformationMethod = PasswordTransformationMethod.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||
switch ( item.ItemId ) {
|
||||
/*case Resource.Id.menu_donate:
|
||||
try {
|
||||
Util.gotoUrl(this, Resource.String.donate_url);
|
||||
} catch (ActivityNotFoundException) {
|
||||
Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
case Resource.Id.menu_toggle_pass:
|
||||
if ( mShowPassword ) {
|
||||
item.SetTitle(Resource.String.show_password);
|
||||
mShowPassword = false;
|
||||
} else {
|
||||
item.SetTitle(Resource.String.menu_hide_password);
|
||||
mShowPassword = true;
|
||||
}
|
||||
setPasswordStyle();
|
||||
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_goto_url:
|
||||
String url;
|
||||
url = mEntry.Strings.ReadSafe (PwDefs.UserNameField);
|
||||
|
||||
// Default http:// if no protocol specified
|
||||
if ( ! url.Contains("://") ) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
|
||||
try {
|
||||
Util.gotoUrl(this, url);
|
||||
} catch (ActivityNotFoundException) {
|
||||
Toast.MakeText(this, Resource.String.no_url_handler, ToastLength.Long).Show();
|
||||
}
|
||||
return true;
|
||||
/* TODO: required?
|
||||
case Resource.Id.menu_copy_user:
|
||||
timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_copy_pass:
|
||||
timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||
return true;
|
||||
*/
|
||||
case Resource.Id.menu_lock:
|
||||
App.setShutdown();
|
||||
SetResult(KeePass.EXIT_LOCK);
|
||||
Finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
739
src/keepass2android/EntryEditActivity.cs
Normal file
@ -0,0 +1,739 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using KeePassLib.Utility;
|
||||
using KeePassLib;
|
||||
using Android.Text;
|
||||
using KeePassLib.Security;
|
||||
using Android.Content.PM;
|
||||
using keepass2android.view;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
||||
public class EntryEditActivity : LockCloseActivity {
|
||||
public const String KEY_ENTRY = "entry";
|
||||
public const String KEY_PARENT = "parent";
|
||||
|
||||
public const int RESULT_OK_ICON_PICKER = (int)Result.FirstUser + 1000;
|
||||
public const int RESULT_OK_PASSWORD_GENERATOR = RESULT_OK_ICON_PICKER + 1;
|
||||
|
||||
private PwEntry mEntry, mEntryInDatabase;
|
||||
private bool mShowPassword = false;
|
||||
private bool mIsNew;
|
||||
private PwIcon mSelectedIconID;
|
||||
private PwUuid mSelectedCustomIconID = PwUuid.Zero;
|
||||
private bool mSelectedIcon = false;
|
||||
|
||||
public static void Launch(Activity act, PwEntry pw) {
|
||||
Intent i = new Intent(act, typeof(EntryEditActivity));
|
||||
|
||||
i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString());
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
public static void Launch(Activity act, PwGroup pw) {
|
||||
Intent i = new Intent(act, typeof(EntryEditActivity));
|
||||
|
||||
PwGroup parent = pw;
|
||||
i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString());
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
private ScrollView scroll;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
SetContentView(Resource.Layout.entry_edit);
|
||||
SetResult(KeePass.EXIT_NORMAL);
|
||||
|
||||
// Likely the app has been killed exit the activity
|
||||
Database db = App.getDB();
|
||||
if ( ! db.Open ) {
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
Intent i = Intent;
|
||||
String uuidBytes = i.GetStringExtra(KEY_ENTRY);
|
||||
|
||||
PwUuid entryId = PwUuid.Zero;
|
||||
if (uuidBytes != null)
|
||||
entryId = new KeePassLib.PwUuid(MemUtil.HexStringToByteArray(uuidBytes));
|
||||
|
||||
PwGroup parentGroup = null;
|
||||
if ( entryId == PwUuid.Zero ) {
|
||||
String groupId = i.GetStringExtra(KEY_PARENT);
|
||||
|
||||
parentGroup = db.groups[new PwUuid(MemUtil.HexStringToByteArray(groupId))];
|
||||
|
||||
mEntryInDatabase = new PwEntry(true, true);
|
||||
mEntryInDatabase.Strings.Set(PwDefs.UserNameField, new ProtectedString(
|
||||
db.pm.MemoryProtection.ProtectUserName, db.pm.DefaultUserName));
|
||||
|
||||
/*KPDesktop
|
||||
* ProtectedString psAutoGen;
|
||||
PwGenerator.Generate(out psAutoGen, Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
|
||||
null, Program.PwGeneratorPool);
|
||||
psAutoGen = psAutoGen.WithProtection(pwDb.MemoryProtection.ProtectPassword);
|
||||
pwe.Strings.Set(PwDefs.PasswordField, psAutoGen);
|
||||
|
||||
int nExpireDays = Program.Config.Defaults.NewEntryExpiresInDays;
|
||||
if(nExpireDays >= 0)
|
||||
{
|
||||
pwe.Expires = true;
|
||||
pwe.ExpiryTime = DateTime.Now.AddDays(nExpireDays);
|
||||
}*/
|
||||
|
||||
if((parentGroup.IconId != PwIcon.Folder) && (parentGroup.IconId != PwIcon.FolderOpen) &&
|
||||
(parentGroup.IconId != PwIcon.FolderPackage))
|
||||
{
|
||||
mEntryInDatabase.IconId = parentGroup.IconId; // Inherit icon from group
|
||||
}
|
||||
mEntryInDatabase.CustomIconUuid = parentGroup.CustomIconUuid;
|
||||
|
||||
/*
|
||||
* KPDesktop
|
||||
if(strDefaultSeq.Length == 0)
|
||||
{
|
||||
PwGroup pg = m_pwEntry.ParentGroup;
|
||||
if(pg != null)
|
||||
{
|
||||
strDefaultSeq = pg.GetAutoTypeSequenceInherited();
|
||||
|
||||
if(strDefaultSeq.Length == 0)
|
||||
{
|
||||
if(PwDefs.IsTanEntry(m_pwEntry))
|
||||
strDefaultSeq = PwDefs.DefaultAutoTypeSequenceTan;
|
||||
else
|
||||
strDefaultSeq = PwDefs.DefaultAutoTypeSequence;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
mIsNew = true;
|
||||
|
||||
} else {
|
||||
|
||||
System.Diagnostics.Debug.Assert(entryId != null);
|
||||
|
||||
mEntryInDatabase = db.entries[entryId];
|
||||
mIsNew = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
mEntry = mEntryInDatabase.CloneDeep();
|
||||
|
||||
fillData();
|
||||
View scrollView = FindViewById(Resource.Id.entry_scroll);
|
||||
scrollView.ScrollBarStyle = ScrollbarStyles.InsideInset;
|
||||
|
||||
ImageButton iconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
iconButton.Click += (sender, evt) => {
|
||||
IconPickerActivity.Launch(this);
|
||||
};
|
||||
|
||||
|
||||
// Generate password button
|
||||
Button generatePassword = (Button) FindViewById(Resource.Id.generate_button);
|
||||
generatePassword.Click += (object sender, EventArgs e) => {
|
||||
|
||||
GeneratePasswordActivity.Launch(this);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Save button
|
||||
Button save = (Button) FindViewById(Resource.Id.entry_save);
|
||||
save.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
|
||||
EntryEditActivity act = this;
|
||||
|
||||
if (!validateBeforeSaving())
|
||||
return;
|
||||
|
||||
PwEntry initialEntry = mEntryInDatabase.CloneDeep();
|
||||
|
||||
PwEntry newEntry = mEntryInDatabase;
|
||||
|
||||
//Clone history and re-assign:
|
||||
newEntry.History = newEntry.History.CloneDeep();
|
||||
|
||||
//Based on KeePass Desktop
|
||||
bool bCreateBackup = (!mIsNew);
|
||||
if(bCreateBackup) newEntry.CreateBackup(null);
|
||||
|
||||
if (mSelectedIcon == false) {
|
||||
if (mIsNew) {
|
||||
newEntry.IconId = PwIcon.Key;
|
||||
} else {
|
||||
// Keep previous icon, if no new one was selected
|
||||
}
|
||||
}
|
||||
else {
|
||||
newEntry.IconId = mSelectedIconID;
|
||||
newEntry.CustomIconUuid = mSelectedCustomIconID;
|
||||
}
|
||||
/* KPDesktop
|
||||
if(m_cbCustomForegroundColor.Checked)
|
||||
newEntry.ForegroundColor = m_clrForeground;
|
||||
else newEntry.ForegroundColor = Color.Empty;
|
||||
if(m_cbCustomBackgroundColor.Checked)
|
||||
newEntry.BackgroundColor = m_clrBackground;
|
||||
else newEntry.BackgroundColor = Color.Empty;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
newEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.pm.MemoryProtection.ProtectTitle,
|
||||
Util.getEditText(act, Resource.Id.entry_title)));
|
||||
newEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.pm.MemoryProtection.ProtectUserName,
|
||||
Util.getEditText(act, Resource.Id.entry_user_name)));
|
||||
|
||||
String pass = Util.getEditText(act, Resource.Id.entry_password);
|
||||
byte[] password = StrUtil.Utf8.GetBytes(pass);
|
||||
newEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.pm.MemoryProtection.ProtectPassword,
|
||||
password));
|
||||
MemUtil.ZeroByteArray(password);
|
||||
|
||||
newEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.pm.MemoryProtection.ProtectUrl,
|
||||
Util.getEditText(act, Resource.Id.entry_url)));
|
||||
newEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.pm.MemoryProtection.ProtectNotes,
|
||||
Util.getEditText(act, Resource.Id.entry_comment)));
|
||||
|
||||
// Delete all non standard strings
|
||||
var keys = newEntry.Strings.GetKeys();
|
||||
foreach (String key in keys)
|
||||
if (PwDefs.IsStandardField(key) == false)
|
||||
newEntry.Strings.Remove(key);
|
||||
|
||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||
|
||||
for (int index = 0; index < container.ChildCount; index++) {
|
||||
View view = container.GetChildAt(index);
|
||||
|
||||
TextView keyView = (TextView)view.FindViewById(Resource.Id.title);
|
||||
String key = keyView.Text;
|
||||
|
||||
TextView valueView = (TextView)view.FindViewById(Resource.Id.value);
|
||||
String value = valueView.Text;
|
||||
|
||||
CheckBox cb = (CheckBox)view.FindViewById(Resource.Id.protection);
|
||||
bool protect = cb.Checked;
|
||||
|
||||
newEntry.Strings.Set(key, new ProtectedString(protect, value));
|
||||
}
|
||||
|
||||
newEntry.Binaries = mEntry.Binaries;
|
||||
newEntry.Expires = mEntry.Expires;
|
||||
if (newEntry.Expires)
|
||||
{
|
||||
newEntry.ExpiryTime = mEntry.ExpiryTime;
|
||||
}
|
||||
|
||||
newEntry.OverrideUrl = Util.getEditText(this,Resource.Id.entry_override_url);
|
||||
|
||||
List<string> vNewTags = StrUtil.StringToTags(Util.getEditText(this,Resource.Id.entry_tags));
|
||||
newEntry.Tags.Clear();
|
||||
foreach(string strTag in vNewTags) newEntry.AddTag(strTag);
|
||||
|
||||
/*KPDesktop
|
||||
|
||||
|
||||
m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked;
|
||||
m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ?
|
||||
AutoTypeObfuscationOptions.UseClipboard :
|
||||
AutoTypeObfuscationOptions.None);
|
||||
|
||||
SaveDefaultSeq();
|
||||
|
||||
newEntry.AutoType = m_atConfig;
|
||||
*/
|
||||
|
||||
|
||||
newEntry.Touch(true, false); // Touch *after* backup
|
||||
|
||||
StrUtil.NormalizeNewLines(newEntry.Strings, true);
|
||||
|
||||
bool bUndoBackup = false;
|
||||
PwCompareOptions cmpOpt = (PwCompareOptions.NullEmptyEquivStd |
|
||||
PwCompareOptions.IgnoreTimes);
|
||||
if(bCreateBackup) cmpOpt |= PwCompareOptions.IgnoreLastBackup;
|
||||
if(newEntry.EqualsEntry(initialEntry, cmpOpt, MemProtCmpMode.CustomOnly))
|
||||
{
|
||||
// No modifications at all => restore last mod time and undo backup
|
||||
newEntry.LastModificationTime = initialEntry.LastModificationTime;
|
||||
bUndoBackup = bCreateBackup;
|
||||
}
|
||||
else if(bCreateBackup)
|
||||
{
|
||||
// If only history items have been modified (deleted) => undo
|
||||
// backup, but without restoring the last mod time
|
||||
PwCompareOptions cmpOptNH = (cmpOpt | PwCompareOptions.IgnoreHistory);
|
||||
if(newEntry.EqualsEntry(initialEntry, cmpOptNH, MemProtCmpMode.CustomOnly))
|
||||
bUndoBackup = true;
|
||||
}
|
||||
if(bUndoBackup) newEntry.History.RemoveAt(newEntry.History.UCount - 1);
|
||||
|
||||
newEntry.MaintainBackups(db.pm);
|
||||
|
||||
|
||||
|
||||
//if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(mEntry.Strings.ReadSafe (PwDefs.TitleField)) ) {
|
||||
// SetResult(KeePass.EXIT_REFRESH);
|
||||
//} else {
|
||||
//it's safer to always update the title as we might add further information in the title like expiry etc.
|
||||
SetResult(KeePass.EXIT_REFRESH_TITLE);
|
||||
//}
|
||||
|
||||
RunnableOnFinish task;
|
||||
OnFinish onFinish = new AfterSave(new Handler(), act);
|
||||
|
||||
if ( mIsNew ) {
|
||||
task = AddEntry.getInstance(this, App.getDB(), newEntry, parentGroup, onFinish);
|
||||
} else {
|
||||
task = new UpdateEntry(this, App.getDB(), initialEntry, newEntry, onFinish);
|
||||
}
|
||||
ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database);
|
||||
pt.run();
|
||||
};
|
||||
|
||||
|
||||
// Respect mask password setting
|
||||
if (mShowPassword) {
|
||||
EditText pass = (EditText) FindViewById(Resource.Id.entry_password);
|
||||
EditText conf = (EditText) FindViewById(Resource.Id.entry_confpassword);
|
||||
|
||||
pass.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
conf.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
}
|
||||
|
||||
scroll = (ScrollView) FindViewById(Resource.Id.entry_scroll);
|
||||
|
||||
Button addButton = (Button) FindViewById(Resource.Id.add_advanced);
|
||||
addButton.Visibility = ViewStates.Visible;
|
||||
addButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||
|
||||
EntryEditSection ees = (EntryEditSection) LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
||||
ees.setData("", new ProtectedString(false, ""));
|
||||
ees.getDeleteButton().Click += (senderEes, eEes) => deleteAdvancedString((View)senderEes);
|
||||
container.AddView(ees);
|
||||
|
||||
// Scroll bottom
|
||||
scroll.Post(() => {
|
||||
scroll.FullScroll(FocusSearchDirection.Down);
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
|
||||
{
|
||||
mEntry.Expires = e.IsChecked;
|
||||
if (e.IsChecked)
|
||||
{
|
||||
if (mEntry.ExpiryTime < DateTime.Now)
|
||||
mEntry.ExpiryTime = DateTime.Now;
|
||||
}
|
||||
updateExpires();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void addBinaryOrAsk(string filename)
|
||||
{
|
||||
string strItem = UrlUtil.GetFileName(filename);
|
||||
|
||||
if(mEntry.Binaries.Get(strItem) != null)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title));
|
||||
|
||||
builder.SetMessage(GetString(Resource.String.AskOverwriteBinary));
|
||||
|
||||
builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
||||
{
|
||||
addBinary(filename, true);
|
||||
}));
|
||||
|
||||
builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
||||
{
|
||||
addBinary(filename, false);
|
||||
}));
|
||||
|
||||
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
||||
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}));
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
|
||||
|
||||
} else
|
||||
addBinary(filename, true);
|
||||
}
|
||||
|
||||
void addBinary(string filename, bool overwrite)
|
||||
{
|
||||
string strItem = UrlUtil.GetFileName(filename);
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
string strFileName = UrlUtil.StripExtension(strItem);
|
||||
string strExtension = "." + UrlUtil.GetExtension(strItem);
|
||||
|
||||
int nTry = 0;
|
||||
while(true)
|
||||
{
|
||||
string strNewName = strFileName + nTry.ToString() + strExtension;
|
||||
if(mEntry.Binaries.Get(strNewName) == null)
|
||||
{
|
||||
strItem = strNewName;
|
||||
break;
|
||||
}
|
||||
|
||||
++nTry;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
byte[] vBytes = File.ReadAllBytes(filename);
|
||||
if(vBytes != null)
|
||||
{
|
||||
ProtectedBinary pb = new ProtectedBinary(false, vBytes);
|
||||
mEntry.Binaries.Set(strItem, pb);
|
||||
}
|
||||
}
|
||||
catch(Exception exAttach)
|
||||
{
|
||||
Toast.MakeText(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, ToastLength.Long).Show();
|
||||
}
|
||||
populateBinaries();
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
switch ((int)resultCode)
|
||||
{
|
||||
case RESULT_OK_ICON_PICKER:
|
||||
mSelectedIconID = (PwIcon) data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID);
|
||||
mSelectedCustomIconID = PwUuid.Zero;
|
||||
String customIconIdString = data.Extras.GetString(IconPickerActivity.KEY_CUSTOM_ICON_ID);
|
||||
if (!String.IsNullOrEmpty(customIconIdString))
|
||||
mSelectedCustomIconID = new PwUuid(MemUtil.HexStringToByteArray(customIconIdString));
|
||||
mSelectedIcon = true;
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
//TODO: custom image
|
||||
currIconButton.SetImageResource(Icons.iconToResId(mSelectedIconID));
|
||||
break;
|
||||
|
||||
case RESULT_OK_PASSWORD_GENERATOR:
|
||||
String generatedPassword = data.GetStringExtra("keepass2android.password.generated_password");
|
||||
EditText password = (EditText) FindViewById(Resource.Id.entry_password);
|
||||
EditText confPassword = (EditText) FindViewById(Resource.Id.entry_confpassword);
|
||||
|
||||
password.Text = generatedPassword;
|
||||
confPassword.Text = generatedPassword;
|
||||
|
||||
break;
|
||||
case (int)Result.Ok:
|
||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE)
|
||||
{
|
||||
String filename = data.DataString;
|
||||
if (filename != null) {
|
||||
if (filename.StartsWith("file://")) {
|
||||
filename = filename.Substring(7);
|
||||
}
|
||||
|
||||
filename = Java.Net.URLDecoder.Decode(filename);
|
||||
addBinaryOrAsk(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case (int)Result.Canceled:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void populateBinaries()
|
||||
{
|
||||
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
||||
binariesGroup.RemoveAllViews();
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent);
|
||||
foreach (KeyValuePair<string, ProtectedBinary> pair in mEntry.Binaries)
|
||||
{
|
||||
String key = pair.Key;
|
||||
Button binaryButton = new Button(this);
|
||||
|
||||
binaryButton.Text = key;
|
||||
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null);
|
||||
binaryButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
Button btnSender = (Button)(sender);
|
||||
mEntry.Binaries.Remove(key);
|
||||
populateBinaries();
|
||||
|
||||
};
|
||||
binariesGroup.AddView(binaryButton,layoutParams);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Button addBinaryButton = new Button(this);
|
||||
addBinaryButton.Text = GetString(Resource.String.add_binary);
|
||||
addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
|
||||
addBinaryButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
Util.showBrowseDialog("/mnt/sdcard", this);
|
||||
};
|
||||
binariesGroup.AddView(addBinaryButton,layoutParams);
|
||||
|
||||
FindViewById(Resource.Id.entry_binaries_label).Visibility = mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
MenuInflater inflater = MenuInflater;
|
||||
inflater.Inflate(Resource.Menu.entry_edit, menu);
|
||||
|
||||
|
||||
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||
if ( mShowPassword ) {
|
||||
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
||||
} else {
|
||||
togglePassword.SetTitle(Resource.String.show_password);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||
switch ( item.ItemId ) {
|
||||
/*case Resource.Id.menu_donate:
|
||||
try {
|
||||
Util.gotoUrl(this, Resource.String.donate_url);
|
||||
} catch (ActivityNotFoundException) {
|
||||
Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
case Resource.Id.menu_toggle_pass:
|
||||
if ( mShowPassword ) {
|
||||
item.SetTitle(Resource.String.show_password);
|
||||
mShowPassword = false;
|
||||
} else {
|
||||
item.SetTitle(Resource.String.menu_hide_password);
|
||||
mShowPassword = true;
|
||||
}
|
||||
setPasswordStyle();
|
||||
return true;
|
||||
case Resource.Id.menu_cancel_edit:
|
||||
Finish();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return base.OnOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setPasswordStyle() {
|
||||
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
||||
TextView confpassword = (TextView) FindViewById(Resource.Id.entry_confpassword);
|
||||
|
||||
if ( mShowPassword ) {
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
|
||||
} else {
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
||||
confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
||||
}
|
||||
}
|
||||
|
||||
void updateExpires()
|
||||
{
|
||||
if (mEntry.Expires)
|
||||
{
|
||||
populateText(Resource.Id.entry_expires, getDateTime(mEntry.ExpiryTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
populateText(Resource.Id.entry_expires, GetString(Resource.String.never));
|
||||
}
|
||||
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).Checked = mEntry.Expires;
|
||||
((EditText)FindViewById(Resource.Id.entry_expires)).Enabled = mEntry.Expires;
|
||||
}
|
||||
|
||||
private void fillData() {
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
App.getDB().drawFactory.assignDrawableTo(currIconButton, Resources, App.getDB().pm, mEntry.IconId, mEntry.CustomIconUuid);
|
||||
|
||||
populateText(Resource.Id.entry_title, mEntry.Strings.ReadSafe (PwDefs.TitleField));
|
||||
populateText(Resource.Id.entry_user_name, mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||
populateText(Resource.Id.entry_url, mEntry.Strings.ReadSafe (PwDefs.UrlField));
|
||||
|
||||
String password = mEntry.Strings.ReadSafe(PwDefs.PasswordField);
|
||||
populateText(Resource.Id.entry_password, password);
|
||||
populateText(Resource.Id.entry_confpassword, password);
|
||||
setPasswordStyle();
|
||||
|
||||
populateText(Resource.Id.entry_comment, mEntry.Strings.ReadSafe (PwDefs.NotesField));
|
||||
|
||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||
|
||||
foreach (var pair in mEntry.Strings)
|
||||
{
|
||||
String key = pair.Key;
|
||||
|
||||
if (!PwDefs.IsStandardField(key)) {
|
||||
EntryEditSection ees = (EntryEditSection) LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
||||
ees.setData(key, pair.Value);
|
||||
ees.getDeleteButton().Click += (sender, e) => deleteAdvancedString((View)sender);
|
||||
container.AddView(ees);
|
||||
}
|
||||
}
|
||||
|
||||
populateBinaries();
|
||||
|
||||
populateText(Resource.Id.entry_override_url, mEntry.OverrideUrl);
|
||||
populateText(Resource.Id.entry_tags, StrUtil.TagsToString(mEntry.Tags, true));
|
||||
|
||||
updateExpires();
|
||||
}
|
||||
private String getDateTime(System.DateTime dt) {
|
||||
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
||||
}
|
||||
|
||||
|
||||
public void deleteAdvancedString(View view) {
|
||||
EntryEditSection section = (EntryEditSection) view.Parent;
|
||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||
|
||||
for (int i = 0; i < container.ChildCount; i++) {
|
||||
EntryEditSection ees = (EntryEditSection) container.GetChildAt(i);
|
||||
if (ees == section) {
|
||||
container.RemoveViewAt(i);
|
||||
container.Invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected bool validateBeforeSaving() {
|
||||
// Require title
|
||||
String title = Util.getEditText(this, Resource.Id.entry_title);
|
||||
if ( title.Length == 0 ) {
|
||||
Toast.MakeText(this, Resource.String.error_title_required, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate password
|
||||
String pass = Util.getEditText(this, Resource.Id.entry_password);
|
||||
String conf = Util.getEditText(this, Resource.Id.entry_confpassword);
|
||||
if ( ! pass.Equals(conf) ) {
|
||||
Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate expiry date
|
||||
DateTime newExpiry = new DateTime();
|
||||
if ((mEntry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry)))
|
||||
{
|
||||
Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntry.ExpiryTime = newExpiry;
|
||||
}
|
||||
|
||||
|
||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||
for (int i = 0; i < container.ChildCount; i++) {
|
||||
EntryEditSection ees = (EntryEditSection) container.GetChildAt(i);
|
||||
|
||||
TextView keyView = (TextView) ees.FindViewById(Resource.Id.title);
|
||||
string key = keyView.Text;
|
||||
|
||||
if (String.IsNullOrEmpty(key)) {
|
||||
Toast.MakeText(this, Resource.String.error_string_key, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void populateText(int viewId, String text) {
|
||||
TextView tv = (TextView) FindViewById(viewId);
|
||||
tv.Text = text;
|
||||
}
|
||||
|
||||
private class AfterSave : OnFinish {
|
||||
Activity act;
|
||||
public AfterSave(Handler handler, Activity act): base(handler) {
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
|
||||
public override void run() {
|
||||
if ( mSuccess ) {
|
||||
act.Finish();
|
||||
} else {
|
||||
displayMessage(act);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
130
src/keepass2android/GeneratePasswordActivity.cs
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
||||
public class GeneratePasswordActivity : LockCloseActivity {
|
||||
private int[] BUTTON_IDS = new int[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
||||
|
||||
public static void Launch(Activity act) {
|
||||
Intent i = new Intent(act, typeof(GeneratePasswordActivity));
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState) {
|
||||
base.OnCreate(savedInstanceState);
|
||||
SetContentView(Resource.Layout.generate_password);
|
||||
SetResult(KeePass.EXIT_NORMAL);
|
||||
|
||||
foreach (int id in BUTTON_IDS) {
|
||||
Button button = (Button) FindViewById(id);
|
||||
button.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
Button b = (Button) sender;
|
||||
|
||||
EditText editText = (EditText) FindViewById(Resource.Id.length);
|
||||
editText.Text = b.Text;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button);
|
||||
genPassButton.Click += (object sender, EventArgs e) => {
|
||||
String password = generatePassword();
|
||||
|
||||
EditText txtPassword = (EditText) FindViewById(Resource.Id.password);
|
||||
txtPassword.Text = password;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Button acceptButton = (Button) FindViewById(Resource.Id.accept_button);
|
||||
acceptButton.Click += (object sender, EventArgs e) => {
|
||||
EditText password = (EditText) FindViewById(Resource.Id.password);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.PutExtra("keepass2android.password.generated_password", password.Text);
|
||||
|
||||
SetResult((Result)EntryEditActivity.RESULT_OK_PASSWORD_GENERATOR, intent);
|
||||
|
||||
Finish();
|
||||
};
|
||||
|
||||
|
||||
Button cancelButton = (Button) FindViewById(Resource.Id.cancel_button);
|
||||
cancelButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
SetResult(Result.Canceled);
|
||||
|
||||
Finish();
|
||||
};
|
||||
|
||||
|
||||
EditText txtPasswordToSet = (EditText) FindViewById(Resource.Id.password);
|
||||
txtPasswordToSet.Text = generatePassword();
|
||||
|
||||
}
|
||||
|
||||
public String generatePassword() {
|
||||
String password = "";
|
||||
|
||||
try {
|
||||
|
||||
int length;
|
||||
if (!int.TryParse(((EditText) FindViewById(Resource.Id.length)).Text, out length))
|
||||
{
|
||||
Toast.MakeText(this, Resource.String.error_wrong_length, ToastLength.Long).Show();
|
||||
return password;
|
||||
}
|
||||
|
||||
|
||||
PasswordGenerator generator = new PasswordGenerator(this);
|
||||
|
||||
password = generator.generatePassword(length,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_minus)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_underline)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_space)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_specials)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_brackets)).Checked);
|
||||
} catch (ArgumentException e) {
|
||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||
}
|
||||
|
||||
return password;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
195
src/keepass2android/GroupActivity.cs
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
using Android.Util;
|
||||
using KeePassLib.Utility;
|
||||
using keepass2android.view;
|
||||
using Android.Content.PM;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden , Theme="@style/NoTitleBar")]
|
||||
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
||||
public class GroupActivity : GroupBaseActivity {
|
||||
|
||||
public const int UNINIT = -1;
|
||||
|
||||
protected bool addGroupEnabled = false;
|
||||
protected bool addEntryEnabled = false;
|
||||
|
||||
private const String TAG = "Group Activity:";
|
||||
|
||||
public static void Launch(Activity act) {
|
||||
Launch(act, null);
|
||||
}
|
||||
|
||||
public static void Launch (Activity act, PwGroup g)
|
||||
{
|
||||
Intent i;
|
||||
|
||||
// Need to use PwDatabase since group may be null
|
||||
PwDatabase db = App.getDB ().pm;
|
||||
|
||||
if (db == null) {
|
||||
// Reached if db is null
|
||||
Log.Debug (TAG, "Tried to launch with null db");
|
||||
return;
|
||||
}
|
||||
|
||||
i = new Intent(act, typeof(GroupActivity));
|
||||
|
||||
if ( g != null ) {
|
||||
i.PutExtra(KEY_ENTRY, g.Uuid.ToHexString());
|
||||
}
|
||||
|
||||
act.StartActivityForResult(i,0);
|
||||
}
|
||||
|
||||
protected PwUuid retrieveGroupId(Intent i)
|
||||
{
|
||||
String uuid = i.GetStringExtra(KEY_ENTRY);
|
||||
|
||||
if ( String.IsNullOrEmpty(uuid) ) {
|
||||
return null;
|
||||
}
|
||||
return new PwUuid(MemUtil.HexStringToByteArray(uuid));
|
||||
}
|
||||
|
||||
protected void setupButtons()
|
||||
{
|
||||
addGroupEnabled = true;
|
||||
addEntryEnabled = !mGroup.Uuid.EqualsValue(App.getDB().root.Uuid);
|
||||
}
|
||||
|
||||
protected override void OnCreate (Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate (savedInstanceState);
|
||||
|
||||
if (IsFinishing) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetResult (KeePass.EXIT_NORMAL);
|
||||
|
||||
Log.Warn (TAG, "Creating group view");
|
||||
Intent intent = Intent;
|
||||
|
||||
PwUuid id = retrieveGroupId (intent);
|
||||
|
||||
Database db = App.getDB ();
|
||||
if (id == null) {
|
||||
mGroup = db.root;
|
||||
} else {
|
||||
mGroup = db.groups[id];
|
||||
}
|
||||
|
||||
Log.Warn (TAG, "Retrieved group");
|
||||
if (mGroup == null) {
|
||||
Log.Warn (TAG, "Group was null");
|
||||
return;
|
||||
}
|
||||
|
||||
setupButtons ();
|
||||
|
||||
if (addGroupEnabled && addEntryEnabled) {
|
||||
SetContentView (new GroupAddEntryView (this));
|
||||
} else if (addGroupEnabled) {
|
||||
SetContentView (new GroupRootView (this));
|
||||
} else if (addEntryEnabled) {
|
||||
throw new Exception ("This mode is not supported.");
|
||||
} else {
|
||||
SetContentView (new GroupViewOnlyView (this));
|
||||
}
|
||||
Log.Warn (TAG, "Set view");
|
||||
|
||||
if (addGroupEnabled) {
|
||||
// Add Group button
|
||||
Button addGroup = (Button)FindViewById (Resource.Id.add_group);
|
||||
addGroup.Click += (object sender, EventArgs e) => {
|
||||
GroupEditActivity.Launch (this, mGroup);
|
||||
};
|
||||
}
|
||||
|
||||
if (addEntryEnabled) {
|
||||
// Add Entry button
|
||||
Button addEntry = (Button)FindViewById (Resource.Id.add_entry);
|
||||
addEntry.Click += (object sender, EventArgs e) => {
|
||||
EntryEditActivity.Launch (this, mGroup);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
setGroupTitle();
|
||||
setGroupIcon();
|
||||
|
||||
ListAdapter = new PwGroupListAdapter(this, mGroup);
|
||||
RegisterForContextMenu(ListView);
|
||||
Log.Warn(TAG, "Finished creating group");
|
||||
|
||||
}
|
||||
|
||||
public override void OnCreateContextMenu(IContextMenu menu, View v,
|
||||
IContextMenuContextMenuInfo menuInfo) {
|
||||
|
||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
ClickView cv = (ClickView) acmi.TargetView;
|
||||
cv.OnCreateMenu(menu, menuInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool OnContextItemSelected(IMenuItem item) {
|
||||
Android.Widget.AdapterView.AdapterContextMenuInfo acmi = (Android.Widget.AdapterView.AdapterContextMenuInfo)item.MenuInfo;
|
||||
ClickView cv = (ClickView) acmi.TargetView;
|
||||
|
||||
return cv.OnContextItemSelected(item);
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
switch (resultCode)
|
||||
{
|
||||
case Result.Ok:
|
||||
String GroupName = data.Extras.GetString(GroupEditActivity.KEY_NAME);
|
||||
int GroupIconID = data.Extras.GetInt(GroupEditActivity.KEY_ICON_ID);
|
||||
GroupBaseActivity act = this;
|
||||
Handler handler = new Handler();
|
||||
AddGroup task = AddGroup.getInstance(this, App.getDB(), GroupName, GroupIconID, mGroup, new RefreshTask(handler, this), false);
|
||||
ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database);
|
||||
pt.run();
|
||||
break;
|
||||
|
||||
case Result.Canceled:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
295
src/keepass2android/GroupBaseActivity.cs
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
using Android.Preferences;
|
||||
using keepass2android.view;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public abstract class GroupBaseActivity : LockCloseListActivity {
|
||||
public const String KEY_ENTRY = "entry";
|
||||
public const String KEY_MODE = "mode";
|
||||
|
||||
public virtual void LaunchActivityForEntry(KeePassLib.PwEntry pwEntry, int pos)
|
||||
{
|
||||
EntryActivity.Launch(this, pwEntry, pos, false);
|
||||
}
|
||||
public GroupBaseActivity ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public GroupBaseActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private ISharedPreferences prefs;
|
||||
|
||||
protected PwGroup mGroup;
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
refreshIfDirty();
|
||||
}
|
||||
|
||||
public override bool OnSearchRequested()
|
||||
{
|
||||
StartActivityForResult(typeof(SearchActivity), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void refreshIfDirty() {
|
||||
Database db = App.getDB();
|
||||
if ( db.dirty.Contains(mGroup) ) {
|
||||
db.dirty.Remove(mGroup);
|
||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
||||
adapter.NotifyDataSetChanged();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||
base.OnListItemClick(l, v, position, id);
|
||||
|
||||
Android.Widget.IListAdapter adapt = ListAdapter;
|
||||
ClickView cv = (ClickView) adapt.GetView(position, null, null);
|
||||
cv.OnClick();
|
||||
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState) {
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
// Likely the app has been killed exit the activity
|
||||
if ( ! App.getDB().Loaded ) {
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
|
||||
SetContentView(new GroupViewOnlyView(this));
|
||||
SetResult(KeePass.EXIT_NORMAL);
|
||||
|
||||
styleScrollBars();
|
||||
|
||||
}
|
||||
|
||||
protected void styleScrollBars() {
|
||||
ListView lv = ListView;
|
||||
lv.ScrollBarStyle =ScrollbarStyles.InsideInset;
|
||||
lv.TextFilterEnabled = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void setGroupTitle()
|
||||
{
|
||||
Button tv = (Button)FindViewById(Resource.Id.group_name);
|
||||
if (tv == null)
|
||||
return;
|
||||
|
||||
if (mGroup != null)
|
||||
{
|
||||
String name = mGroup.Name;
|
||||
if (!String.IsNullOrEmpty(name))
|
||||
{
|
||||
tv.Text = name;
|
||||
} else
|
||||
{
|
||||
tv.Text = GetText(Resource.String.root);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if ((mGroup != null) && (mGroup.IsVirtual == false) && (mGroup.ParentGroup != null))
|
||||
{
|
||||
tv.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
Finish();
|
||||
};
|
||||
} else
|
||||
{
|
||||
tv.SetCompoundDrawables(null, null, null, null);
|
||||
tv.Clickable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setGroupIcon() {
|
||||
if (mGroup != null) {
|
||||
ImageView iv = (ImageView) FindViewById(Resource.Id.icon);
|
||||
App.getDB().drawFactory.assignDrawableTo(iv, Resources, App.getDB().pm, mGroup.IconId, mGroup.CustomIconUuid);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
MenuInflater inflater = MenuInflater;
|
||||
inflater.Inflate(Resource.Menu.group, menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setSortMenuText(IMenu menu) {
|
||||
bool sortByName = prefs.GetBoolean(GetString(Resource.String.sort_key), Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||
|
||||
int resId;
|
||||
if ( sortByName ) {
|
||||
resId = Resource.String.sort_db;
|
||||
} else {
|
||||
resId = Resource.String.sort_name;
|
||||
}
|
||||
|
||||
menu.FindItem(Resource.Id.menu_sort).SetTitle(resId);
|
||||
|
||||
}
|
||||
|
||||
public override bool OnPrepareOptionsMenu(IMenu menu) {
|
||||
if ( ! base.OnPrepareOptionsMenu(menu) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setSortMenuText(menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||
switch ( item.ItemId ) {
|
||||
/*case Resource.Id.menu_donate:
|
||||
try {
|
||||
Util.gotoUrl(this, Resource.String.donate_url);
|
||||
} catch (ActivityNotFoundException) {
|
||||
Toast.MakeText(this, Resource.String.error_failed_to_launch_link, ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
case Resource.Id.menu_lock:
|
||||
App.setShutdown();
|
||||
SetResult(KeePass.EXIT_LOCK);
|
||||
Finish();
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_search:
|
||||
OnSearchRequested();
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_app_settings:
|
||||
AppSettingsActivity.Launch(this);
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_change_master_key:
|
||||
setPassword();
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_sort:
|
||||
toggleSort();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return base.OnOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void toggleSort() {
|
||||
// Toggle setting
|
||||
String sortKey = GetString(Resource.String.sort_key);
|
||||
bool sortByName = prefs.GetBoolean(sortKey, Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||
ISharedPreferencesEditor editor = prefs.Edit();
|
||||
editor.PutBoolean(sortKey, ! sortByName);
|
||||
EditorCompat.apply(editor);
|
||||
|
||||
// Refresh menu titles
|
||||
ActivityCompat.invalidateOptionsMenu(this);
|
||||
|
||||
// Mark all groups as dirty now to refresh them on load
|
||||
Database db = App.getDB();
|
||||
db.markAllGroupsAsDirty();
|
||||
// We'll manually refresh this group so we can remove it
|
||||
db.dirty.Remove(mGroup);
|
||||
|
||||
// Tell the adapter to refresh it's list
|
||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
||||
adapter.NotifyDataSetChanged();
|
||||
|
||||
}
|
||||
|
||||
private void setPassword() {
|
||||
SetPasswordDialog dialog = new SetPasswordDialog(this);
|
||||
dialog.Show();
|
||||
}
|
||||
|
||||
public class RefreshTask : OnFinish {
|
||||
GroupBaseActivity act;
|
||||
public RefreshTask(Handler handler, GroupBaseActivity act):base(handler) {
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
public override void run() {
|
||||
if ( mSuccess) {
|
||||
act.refreshIfDirty();
|
||||
} else {
|
||||
displayMessage(act);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class AfterDeleteGroup : OnFinish {
|
||||
GroupBaseActivity act;
|
||||
|
||||
public AfterDeleteGroup(Handler handler, GroupBaseActivity act):base(handler) {
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
|
||||
public override void run() {
|
||||
if ( mSuccess) {
|
||||
act.refreshIfDirty();
|
||||
} else {
|
||||
mHandler.Post( () => {
|
||||
Toast.MakeText(act, "Unrecoverable error: " + mMessage, ToastLength.Long).Show();
|
||||
});
|
||||
|
||||
App.setShutdown();
|
||||
act.Finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
109
src/keepass2android/GroupEditActivity.cs
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", Theme="@style/Dialog")]
|
||||
public class GroupEditActivity : LifecycleDebugActivity
|
||||
{
|
||||
public const String KEY_PARENT = "parent";
|
||||
public const String KEY_NAME = "name";
|
||||
public const String KEY_ICON_ID = "icon_id";
|
||||
|
||||
private int mSelectedIconID;
|
||||
|
||||
public static void Launch(Activity act, PwGroup pw)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(GroupEditActivity));
|
||||
|
||||
PwGroup parent = pw;
|
||||
i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString());
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
protected override void OnCreate (Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate (savedInstanceState);
|
||||
SetContentView (Resource.Layout.group_edit);
|
||||
SetTitle (Resource.String.add_group_title);
|
||||
|
||||
ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button);
|
||||
iconButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
IconPickerActivity.Launch (this);
|
||||
};
|
||||
mSelectedIconID = (int) PwIcon.FolderOpen;
|
||||
iconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID));
|
||||
|
||||
Button okButton = (Button)FindViewById (Resource.Id.ok);
|
||||
okButton.Click += (object sender, EventArgs e) => {
|
||||
TextView nameField = (TextView)FindViewById (Resource.Id.group_name);
|
||||
String name = nameField.Text;
|
||||
|
||||
if (name.Length > 0) {
|
||||
Intent intent = new Intent ();
|
||||
|
||||
intent.PutExtra (KEY_NAME, name);
|
||||
intent.PutExtra (KEY_ICON_ID, mSelectedIconID);
|
||||
SetResult (Result.Ok, intent);
|
||||
|
||||
Finish ();
|
||||
} else {
|
||||
Toast.MakeText (this, Resource.String.error_no_name, ToastLength.Long).Show ();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Button cancel = (Button)FindViewById (Resource.Id.cancel);
|
||||
cancel.Click += (object sender, EventArgs e) => {
|
||||
Intent intent = new Intent ();
|
||||
SetResult (Result.Canceled, intent);
|
||||
|
||||
Finish ();
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
switch ((int)resultCode)
|
||||
{
|
||||
case EntryEditActivity.RESULT_OK_ICON_PICKER:
|
||||
mSelectedIconID = data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID);
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
currIconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
118
src/keepass2android/IconPickerActivity.cs
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
||||
public class IconPickerActivity : LockCloseActivity
|
||||
{
|
||||
public const String KEY_ICON_ID = "icon_id";
|
||||
public const String KEY_CUSTOM_ICON_ID = "custom_icon_id";
|
||||
|
||||
public static void Launch(Activity act)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(IconPickerActivity));
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
SetContentView(Resource.Layout.icon_picker);
|
||||
|
||||
GridView currIconGridView = (GridView)FindViewById(Resource.Id.IconGridView);
|
||||
currIconGridView.Adapter = new ImageAdapter(this, this);
|
||||
|
||||
currIconGridView.ItemClick += (sender, e) => {
|
||||
|
||||
Intent intent = new Intent();
|
||||
|
||||
intent.PutExtra(KEY_ICON_ID, e.Position);
|
||||
SetResult((Result)EntryEditActivity.RESULT_OK_ICON_PICKER, intent);
|
||||
|
||||
Finish();
|
||||
};
|
||||
}
|
||||
|
||||
public class ImageAdapter : BaseAdapter
|
||||
{
|
||||
Context mContext;
|
||||
|
||||
IconPickerActivity act;
|
||||
|
||||
public ImageAdapter(Context c, IconPickerActivity act)
|
||||
{
|
||||
mContext = c;
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
/* Return number of KeePass icons */
|
||||
return Icons.count();
|
||||
}
|
||||
}
|
||||
|
||||
public override Java.Lang.Object GetItem(int position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View currView;
|
||||
if(convertView == null)
|
||||
{
|
||||
LayoutInflater li = (LayoutInflater) act.GetSystemService(Context.LayoutInflaterService);
|
||||
currView = li.Inflate(Resource.Layout.icon, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
currView = convertView;
|
||||
}
|
||||
|
||||
TextView tv = (TextView) currView.FindViewById(Resource.Id.icon_text);
|
||||
tv.Text = "" + position;
|
||||
ImageView iv = (ImageView) currView.FindViewById(Resource.Id.icon_image);
|
||||
iv.SetImageResource(Icons.iconToResId((KeePassLib.PwIcon)position));
|
||||
|
||||
return currView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
94
src/keepass2android/KeePass.cs
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.OS;
|
||||
|
||||
using keepass2android.view;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", MainLauncher = true, Theme="@style/Base")]
|
||||
[IntentFilter (new[]{Intent.ActionView},
|
||||
DataScheme="file",
|
||||
DataMimeType="*/*",
|
||||
DataHost="*",
|
||||
DataPathPattern=".*\\.kdbx", //TODO http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i
|
||||
//http://stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-extension
|
||||
Categories=new[]{Intent.CategoryDefault, Intent.CategoryBrowsable})]
|
||||
public class KeePass : LifecycleDebugActivity
|
||||
{
|
||||
public const Android.App.Result EXIT_NORMAL = Android.App.Result.FirstUser;
|
||||
public const Android.App.Result EXIT_LOCK = Android.App.Result.FirstUser+1;
|
||||
public const Android.App.Result EXIT_REFRESH = Android.App.Result.FirstUser+2;
|
||||
public const Android.App.Result EXIT_REFRESH_TITLE = Android.App.Result.FirstUser+3;
|
||||
public const Android.App.Result EXIT_FORCE_LOCK = Android.App.Result.FirstUser+4;
|
||||
public const Android.App.Result EXIT_QUICK_UNLOCK = Android.App.Result.FirstUser+5;
|
||||
public const Android.App.Result EXIT_CLOSE_AFTER_SEARCH = Android.App.Result.FirstUser+6;
|
||||
public const Android.App.Result EXIT_CHANGE_DB = Android.App.Result.FirstUser+7;
|
||||
public const Android.App.Result EXIT_FORCE_LOCK_AND_CHANGE_DB = Android.App.Result.FirstUser+8;
|
||||
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
Android.Util.Log.Debug("DEBUG","KeePass.OnCreate");
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
Android.Util.Log.Debug("DEBUG","KeePass.OnResume");
|
||||
}
|
||||
|
||||
|
||||
protected override void OnStart() {
|
||||
base.OnStart();
|
||||
Android.Util.Log.Debug("DEBUG","KeePass.OnStart");
|
||||
startFileSelect();
|
||||
}
|
||||
|
||||
private void startFileSelect() {
|
||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||
//TEST Intent intent = new Intent(this, typeof(EntryActivity));
|
||||
//Intent intent = new Intent(this, typeof(SearchActivity));
|
||||
//Intent intent = new Intent(this, typeof(QuickUnlock));
|
||||
|
||||
StartActivityForResult(intent, 0);
|
||||
Finish();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDestroy() {
|
||||
Android.Util.Log.Debug("DEBUG","KeePass.OnDestry"+IsFinishing.ToString());
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
71
src/keepass2android/KeyFileException.cs
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public class KeyFileException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
|
||||
/// </summary>
|
||||
public KeyFileException ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
|
||||
/// </summary>
|
||||
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
|
||||
public KeyFileException (string message) : base (message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
|
||||
/// </summary>
|
||||
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
|
||||
/// <param name="inner">The exception that is the cause of the current exception. </param>
|
||||
public KeyFileException (string message, Exception inner) : base (message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
|
||||
/// </summary>
|
||||
/// <param name="context">The contextual information about the source or destination.</param>
|
||||
/// <param name="info">The object that holds the serialized object data.</param>
|
||||
protected KeyFileException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
93
src/keepass2android/LifecycleDebugActivity.cs
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public abstract class LifecycleDebugActivity : Activity
|
||||
{
|
||||
public LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LifecycleDebugActivity()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
string className = null;
|
||||
string ClassName
|
||||
{
|
||||
get {
|
||||
if (className == null)
|
||||
className = this.GetType().Name;
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStart");
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate");
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString());
|
||||
}
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
base.OnStop();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
53
src/keepass2android/LockCloseActivity.cs
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class LockCloseActivity : LockingActivity {
|
||||
|
||||
IOConnectionInfo mIoc;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
mIoc = App.getDB().mIoc;
|
||||
}
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
TimeoutHelper.checkShutdown(this, mIoc);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
61
src/keepass2android/LockCloseListActivity.cs
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class LockCloseListActivity : LockingListActivity {
|
||||
public LockCloseListActivity()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IOConnectionInfo mIoc;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
mIoc = App.getDB().mIoc;
|
||||
}
|
||||
|
||||
public LockCloseListActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
TimeoutHelper.checkShutdown(this, mIoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
64
src/keepass2android/LockingActivity.cs
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class LockingActivity : LifecycleDebugActivity {
|
||||
|
||||
public LockingActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LockingActivity()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPause() {
|
||||
base.OnPause();
|
||||
|
||||
TimeoutHelper.pause(this);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
TimeoutHelper.resume(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
53
src/keepass2android/LockingClosePreferenceActivity.cs
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class LockingClosePreferenceActivity : LockingPreferenceActivity {
|
||||
|
||||
|
||||
IOConnectionInfo mIoc;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
mIoc = App.getDB().mIoc;
|
||||
}
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
TimeoutHelper.checkShutdown(this, mIoc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
96
src/keepass2android/LockingListActivity.cs
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class LockingListActivity : ListActivity {
|
||||
|
||||
|
||||
public LockingListActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
public LockingListActivity ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
string className = null;
|
||||
string ClassName
|
||||
{
|
||||
get {
|
||||
if (className == null)
|
||||
className = this.GetType().Name;
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
TimeoutHelper.resume(this);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStart");
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate");
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
GC.Collect();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString());
|
||||
}
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
TimeoutHelper.pause(this);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
base.OnStop();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
97
src/keepass2android/LockingPreferenceActivity.cs
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class LockingPreferenceActivity : PreferenceActivity {
|
||||
|
||||
public LockingPreferenceActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
public LockingPreferenceActivity ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
string className = null;
|
||||
string ClassName
|
||||
{
|
||||
get {
|
||||
if (className == null)
|
||||
className = this.GetType().Name;
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
TimeoutHelper.resume(this);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStart");
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnCreate");
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
GC.Collect();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnDestroy"+IsFinishing.ToString());
|
||||
}
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
TimeoutHelper.pause(this);
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
base.OnStop();
|
||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnStop");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
570
src/keepass2android/PasswordActivity.cs
Normal file
@ -0,0 +1,570 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Java.Net;
|
||||
using Android.Preferences;
|
||||
using Java.IO;
|
||||
using Android.Text;
|
||||
using Android.Content.PM;
|
||||
using Android.Text.Method;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")]
|
||||
public class PasswordActivity : LockingActivity {
|
||||
bool mShowPassword = false;
|
||||
|
||||
public const String KEY_DEFAULT_FILENAME = "defaultFileName";
|
||||
|
||||
public const String KEY_FILENAME = "fileName";
|
||||
private const String KEY_KEYFILE = "keyFile";
|
||||
private const String KEY_SERVERUSERNAME = "serverCredUser";
|
||||
private const String KEY_SERVERPASSWORD = "serverCredPwd";
|
||||
private const String KEY_SERVERCREDMODE = "serverCredRememberMode";
|
||||
|
||||
private const String VIEW_INTENT = "android.intent.action.VIEW";
|
||||
|
||||
private IOConnectionInfo mIoConnection;
|
||||
private String mKeyFile;
|
||||
private bool mRememberKeyfile;
|
||||
ISharedPreferences prefs;
|
||||
|
||||
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PasswordActivity()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void PutIoConnectionToIntent(IOConnectionInfo ioc, Android.Content.Intent i)
|
||||
{
|
||||
i.PutExtra(KEY_FILENAME, ioc.Path);
|
||||
i.PutExtra(KEY_SERVERUSERNAME, ioc.UserName);
|
||||
i.PutExtra(KEY_SERVERPASSWORD, ioc.Password);
|
||||
i.PutExtra(KEY_SERVERCREDMODE, (int)ioc.CredSaveMode);
|
||||
}
|
||||
|
||||
public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i)
|
||||
{
|
||||
ioc.Path = i.GetStringExtra(KEY_FILENAME);
|
||||
ioc.UserName = i.GetStringExtra(KEY_SERVERUSERNAME) ?? "";
|
||||
ioc.Password = i.GetStringExtra(KEY_SERVERPASSWORD) ?? "";
|
||||
ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KEY_SERVERCREDMODE, (int) IOCredSaveMode.NoSave);
|
||||
}
|
||||
|
||||
public static void Launch(Activity act, String fileName, String urlToSearchFor) {
|
||||
Java.IO.File dbFile = new Java.IO.File(fileName);
|
||||
if ( ! dbFile.Exists() ) {
|
||||
throw new Java.IO.FileNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
Intent i = new Intent(act, typeof(PasswordActivity));
|
||||
i.PutExtra(KEY_FILENAME, fileName);
|
||||
i.PutExtra(FileSelectActivity.UrlToSearch_key, urlToSearchFor);
|
||||
act.StartActivityForResult(i, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void Launch(Activity act, String fileName) {
|
||||
Launch(act, IOConnectionInfo.FromPath(fileName), null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void Launch(Activity act, IOConnectionInfo ioc, String urlToSearchFor)
|
||||
{
|
||||
if (ioc.IsLocalFile())
|
||||
{
|
||||
Launch(act, ioc.Path, urlToSearchFor);
|
||||
return;
|
||||
}
|
||||
|
||||
Intent i = new Intent(act, typeof(PasswordActivity));
|
||||
PutIoConnectionToIntent(ioc, i);
|
||||
|
||||
i.PutExtra(FileSelectActivity.UrlToSearch_key, urlToSearchFor);
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
|
||||
}
|
||||
|
||||
public void LaunchNextActivity()
|
||||
{
|
||||
|
||||
if (String.IsNullOrEmpty(mUrlToSearchFor))
|
||||
GroupActivity.Launch(this);
|
||||
else
|
||||
{
|
||||
ShareUrlResults.Launch(this, mUrlToSearchFor);
|
||||
}
|
||||
}
|
||||
|
||||
void unloadDatabase()
|
||||
{
|
||||
App.getDB().Clear();
|
||||
StopService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
||||
}
|
||||
|
||||
void lockDatabase()
|
||||
{
|
||||
SetResult(KeePass.EXIT_LOCK);
|
||||
setEditText(Resource.Id.password, "");
|
||||
if (App.getDB().QuickUnlockEnabled)
|
||||
App.getDB().Locked = true;
|
||||
else
|
||||
{
|
||||
unloadDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
void lockAndClose()
|
||||
{
|
||||
lockDatabase();
|
||||
Finish();
|
||||
|
||||
}
|
||||
|
||||
bool tryStartQuickUnlock()
|
||||
{
|
||||
if (!App.getDB().QuickUnlockEnabled)
|
||||
return false;
|
||||
|
||||
if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpPassword)) == false)
|
||||
return false;
|
||||
KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword));
|
||||
String password = kcpPassword.Password.ReadString();
|
||||
|
||||
if (password.Length == 0)
|
||||
return false;
|
||||
|
||||
App.getDB().Locked = true;
|
||||
|
||||
Intent i = new Intent(this, typeof(QuickUnlock));
|
||||
PutIoConnectionToIntent(mIoConnection, i);
|
||||
Android.Util.Log.Debug("DEBUG","Starting QuickUnlock");
|
||||
StartActivityForResult(i,0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void StartQuickUnlockForegroundService()
|
||||
{
|
||||
if (App.getDB().QuickUnlockEnabled)
|
||||
{
|
||||
StartService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
||||
}
|
||||
}
|
||||
|
||||
bool startedWithActivityResult = false;
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
startedWithActivityResult = true;
|
||||
Android.Util.Log.Debug("DEBUG","PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode);
|
||||
|
||||
if (resultCode != KeePass.EXIT_CLOSE_AFTER_SEARCH)
|
||||
{
|
||||
//Stop service when app activity is left
|
||||
StopService(new Intent(this, typeof(CopyToClipboardService)));
|
||||
}
|
||||
|
||||
//NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works)
|
||||
switch(resultCode) {
|
||||
|
||||
case KeePass.EXIT_NORMAL:
|
||||
if (!tryStartQuickUnlock())
|
||||
{
|
||||
setEditText(Resource.Id.password, "");
|
||||
;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeePass.EXIT_LOCK:
|
||||
if (!tryStartQuickUnlock())
|
||||
{
|
||||
lockAndClose();
|
||||
}
|
||||
break;
|
||||
case KeePass.EXIT_FORCE_LOCK:
|
||||
setEditText(Resource.Id.password, "");
|
||||
unloadDatabase();
|
||||
break;
|
||||
case KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB:
|
||||
unloadDatabase();
|
||||
Finish();
|
||||
break;
|
||||
case KeePass.EXIT_CHANGE_DB:
|
||||
lockAndClose();
|
||||
break;
|
||||
case KeePass.EXIT_CLOSE_AFTER_SEARCH:
|
||||
SetResult(KeePass.EXIT_CLOSE_AFTER_SEARCH);
|
||||
Finish();
|
||||
break;
|
||||
case KeePass.EXIT_QUICK_UNLOCK:
|
||||
App.getDB().Locked = false;
|
||||
LaunchNextActivity();
|
||||
break;
|
||||
|
||||
case Android.App.Result.Ok:
|
||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE) {
|
||||
String filename = data.DataString;
|
||||
if (filename != null) {
|
||||
if (filename.StartsWith("file://")) {
|
||||
filename = filename.Substring(7);
|
||||
}
|
||||
|
||||
filename = URLDecoder.Decode(filename);
|
||||
|
||||
EditText fn = (EditText) FindViewById(Resource.Id.pass_keyfile);
|
||||
fn.Text = filename;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal string mUrlToSearchFor;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
Intent i = Intent;
|
||||
String action = i.Action;
|
||||
|
||||
prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
mRememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
||||
|
||||
mIoConnection = new IOConnectionInfo();
|
||||
|
||||
if (action != null && action.Equals(VIEW_INTENT))
|
||||
{
|
||||
mIoConnection.Path = i.DataString;
|
||||
|
||||
if (! mIoConnection.Path.Substring(0, 7).Equals("file://"))
|
||||
{
|
||||
//TODO: this might no longer be required as we can handle http(s) and ftp as well (but we need server credentials therefore)
|
||||
Toast.MakeText(this, Resource.String.error_can_not_handle_uri, ToastLength.Long).Show();
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mIoConnection.Path = URLDecoder.Decode(mIoConnection.Path.Substring(7, mIoConnection.Path.Length));
|
||||
|
||||
if (mIoConnection.Path.Length == 0)
|
||||
{
|
||||
// No file name
|
||||
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
File dbFile = new File(mIoConnection.Path);
|
||||
if (! dbFile.Exists())
|
||||
{
|
||||
// File does not exist
|
||||
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mKeyFile = getKeyFile(mIoConnection.Path);
|
||||
|
||||
} else
|
||||
{
|
||||
SetIoConnectionFromIntent(mIoConnection, i);
|
||||
mKeyFile = i.GetStringExtra(KEY_KEYFILE);
|
||||
if (mKeyFile == null || mKeyFile.Length == 0)
|
||||
{
|
||||
mKeyFile = getKeyFile(mIoConnection.Path);
|
||||
}
|
||||
}
|
||||
|
||||
this.mUrlToSearchFor = i.GetStringExtra(FileSelectActivity.UrlToSearch_key);
|
||||
|
||||
SetContentView(Resource.Layout.password);
|
||||
populateView();
|
||||
|
||||
Button confirmButton = (Button)FindViewById(Resource.Id.pass_ok);
|
||||
confirmButton.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
String pass = GetEditText(Resource.Id.password);
|
||||
String key = GetEditText(Resource.Id.pass_keyfile);
|
||||
if (pass.Length == 0 && key.Length == 0)
|
||||
{
|
||||
errorMessage(Resource.String.error_nopass);
|
||||
return;
|
||||
}
|
||||
|
||||
String fileName = GetEditText(Resource.Id.filename);
|
||||
|
||||
|
||||
// Clear before we load
|
||||
unloadDatabase();
|
||||
|
||||
// Clear the shutdown flag
|
||||
App.clearShutdown();
|
||||
|
||||
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
||||
App.getDB().QuickUnlockEnabled = cbQuickUnlock.Checked;
|
||||
App.getDB().QuickUnlockKeyLength = int.Parse(prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default)));
|
||||
|
||||
Handler handler = new Handler();
|
||||
LoadDB task = new LoadDB(App.getDB(), this, mIoConnection, pass, key, new AfterLoad(handler, this));
|
||||
ProgressTask pt = new ProgressTask(this, task, Resource.String.loading_database);
|
||||
pt.run();
|
||||
};
|
||||
|
||||
/*CheckBox checkBox = (CheckBox) FindViewById(Resource.Id.show_password);
|
||||
// Show or hide password
|
||||
checkBox.CheckedChange += delegate(object sender, CompoundButton.CheckedChangeEventArgs e) {
|
||||
|
||||
TextView password = (TextView) FindViewById(Resource.Id.password);
|
||||
if ( e.IsChecked ) {
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
} else {
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
||||
}
|
||||
};
|
||||
*/
|
||||
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
|
||||
btnTogglePassword.Click += (object sender, EventArgs e) => {
|
||||
mShowPassword = !mShowPassword;
|
||||
TextView password = (TextView)FindViewById(Resource.Id.password);
|
||||
if (mShowPassword)
|
||||
{
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||
} else
|
||||
{
|
||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
||||
}
|
||||
};
|
||||
|
||||
CheckBox defaultCheck = (CheckBox)FindViewById(Resource.Id.default_database);
|
||||
///Don't allow the current file to be the default if we don't have stored credentials
|
||||
if ((mIoConnection.IsLocalFile() == false) && (mIoConnection.CredSaveMode != IOCredSaveMode.SaveCred))
|
||||
{
|
||||
defaultCheck.Enabled = false;
|
||||
} else
|
||||
{
|
||||
defaultCheck.Enabled = true;
|
||||
}
|
||||
defaultCheck.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
|
||||
{
|
||||
String newDefaultFileName;
|
||||
|
||||
if (e.IsChecked)
|
||||
{
|
||||
newDefaultFileName = mIoConnection.Path;
|
||||
} else
|
||||
{
|
||||
newDefaultFileName = "";
|
||||
}
|
||||
|
||||
ISharedPreferencesEditor editor = prefs.Edit();
|
||||
editor.PutString(KEY_DEFAULT_FILENAME, newDefaultFileName);
|
||||
EditorCompat.apply(editor);
|
||||
};
|
||||
|
||||
ImageButton browse = (ImageButton)FindViewById(Resource.Id.browse_button);
|
||||
browse.Click += (object sender, EventArgs evt) =>
|
||||
{
|
||||
if (Interaction.isIntentAvailable(this, Intents.FILE_BROWSE))
|
||||
{
|
||||
Intent intent = new Intent(Intents.FILE_BROWSE);
|
||||
|
||||
if (!String.IsNullOrEmpty(mIoConnection.Path))
|
||||
{
|
||||
File keyfile = new File(mIoConnection.Path);
|
||||
File parent = keyfile.ParentFile;
|
||||
if (parent != null)
|
||||
{
|
||||
intent.SetData(Android.Net.Uri.Parse("file://" + parent.AbsolutePath));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
StartActivityForResult(intent, Intents.REQUEST_CODE_FILE_BROWSE);
|
||||
} catch (ActivityNotFoundException)
|
||||
{
|
||||
BrowserDialog diag = new BrowserDialog(this);
|
||||
diag.Show();
|
||||
}
|
||||
} else
|
||||
{
|
||||
BrowserDialog diag = new BrowserDialog(this);
|
||||
diag.Show();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
retrieveSettings();
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
// If the application was shutdown make sure to clear the password field, if it
|
||||
// was saved in the instance state
|
||||
if (App.isShutdown()) {
|
||||
lockDatabase();
|
||||
}
|
||||
|
||||
// Clear the shutdown flag
|
||||
App.clearShutdown();
|
||||
|
||||
if (startedWithActivityResult)
|
||||
return;
|
||||
|
||||
if (App.getDB().Loaded && (App.getDB().mIoc != null)
|
||||
&& (mIoConnection != null) && (App.getDB().mIoc.GetDisplayName() == mIoConnection.GetDisplayName()))
|
||||
{
|
||||
if (App.getDB().Locked == false)
|
||||
{
|
||||
LaunchNextActivity();
|
||||
}
|
||||
else
|
||||
{
|
||||
tryStartQuickUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveSettings() {
|
||||
String defaultFilename = prefs.GetString(KEY_DEFAULT_FILENAME, "");
|
||||
if (!String.IsNullOrEmpty(mIoConnection.Path) && mIoConnection.Path.Equals(defaultFilename)) {
|
||||
CheckBox checkbox = (CheckBox) FindViewById(Resource.Id.default_database);
|
||||
checkbox.Checked = true;
|
||||
}
|
||||
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
||||
cbQuickUnlock.Checked = prefs.GetBoolean(GetString(Resource.String.QuickUnlockDefaultEnabled_key), true);
|
||||
}
|
||||
|
||||
private String getKeyFile(String filename) {
|
||||
if ( mRememberKeyfile ) {
|
||||
FileDbHelper dbHelp = App.fileDbHelper;
|
||||
|
||||
String keyfile = dbHelp.getFileByName(filename);
|
||||
|
||||
return keyfile;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private void populateView() {
|
||||
setEditText(Resource.Id.filename, mIoConnection.GetDisplayName());
|
||||
setEditText(Resource.Id.pass_keyfile, mKeyFile);
|
||||
}
|
||||
|
||||
/*
|
||||
private void errorMessage(CharSequence text)
|
||||
{
|
||||
Toast.MakeText(this, text, ToastLength.Long).Show();
|
||||
}
|
||||
*/
|
||||
|
||||
private void errorMessage(int resId)
|
||||
{
|
||||
Toast.MakeText(this, resId, ToastLength.Long).Show();
|
||||
}
|
||||
|
||||
private String GetEditText(int resId) {
|
||||
return Util.getEditText(this, resId);
|
||||
}
|
||||
|
||||
private void setEditText(int resId, String str) {
|
||||
TextView te = (TextView) FindViewById(resId);
|
||||
//assert(te == null);
|
||||
|
||||
if (te != null) {
|
||||
te.Text = str;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
||||
MenuInflater inflate = MenuInflater;
|
||||
inflate.Inflate(Resource.Menu.password, menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||
switch ( item.ItemId ) {
|
||||
case Resource.Id.menu_about:
|
||||
AboutDialog dialog = new AboutDialog(this);
|
||||
dialog.Show();
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_app_settings:
|
||||
AppSettingsActivity.Launch(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private class AfterLoad : OnFinish {
|
||||
|
||||
|
||||
PasswordActivity act;
|
||||
public AfterLoad(Handler handler, PasswordActivity act):base(handler) {
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
|
||||
public override void run() {
|
||||
if ( mSuccess ) {
|
||||
act.StartQuickUnlockForegroundService();
|
||||
act.LaunchNextActivity();
|
||||
} else {
|
||||
displayMessage(act);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
87
src/keepass2android/ProgressTask.cs
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Java.Lang;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class ProgressTask {
|
||||
private Context mCtx;
|
||||
private Handler mHandler;
|
||||
private RunnableOnFinish mTask;
|
||||
private ProgressDialog mPd;
|
||||
|
||||
public ProgressTask(Context ctx, RunnableOnFinish task, int messageId) {
|
||||
mCtx = ctx;
|
||||
mTask = task;
|
||||
mHandler = new Handler();
|
||||
|
||||
// Show process dialog
|
||||
mPd = new ProgressDialog(mCtx);
|
||||
mPd.SetTitle(ctx.GetText(Resource.String.progress_title));
|
||||
mPd.SetMessage(ctx.GetText(messageId));
|
||||
|
||||
// Set code to run when this is finished
|
||||
mTask.setStatus(new UpdateStatus(ctx, mHandler, mPd));
|
||||
mTask.mFinish = new AfterTask(task.mFinish, mHandler, mPd);
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Show process dialog
|
||||
mPd.Show();
|
||||
|
||||
|
||||
// Start Thread to Run task
|
||||
Thread t = new Thread(mTask.run);
|
||||
t.Start();
|
||||
|
||||
}
|
||||
|
||||
private class AfterTask : OnFinish {
|
||||
|
||||
ProgressDialog mPd;
|
||||
|
||||
public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler)
|
||||
{
|
||||
mPd = pd;
|
||||
}
|
||||
|
||||
public override void run() {
|
||||
base.run();
|
||||
|
||||
// Remove the progress dialog
|
||||
mHandler.Post(delegate() {mPd.Dismiss();});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
8
src/keepass2android/Properties/AndroidManifest.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="0.5 beta" package="keepass2android.keepass2android" android:installLocation="preferExternal">
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14" />
|
||||
<application android:label="keepass2android" android:icon="@drawable/ic_launcher"></application>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
44
src/keepass2android/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Android.App;
|
||||
|
||||
// Information about this assembly is defined by the following attributes.
|
||||
// Change them to the values specific to your project.
|
||||
|
||||
[assembly: AssemblyTitle("keepass2android")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("Philipp Crocoll")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0")]
|
||||
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
||||
|
47
src/keepass2android/PwGroupEqualityFromIdComparer.cs
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
|
||||
{
|
||||
#region IEqualityComparer implementation
|
||||
public bool Equals (PwGroup x, PwGroup y)
|
||||
{
|
||||
return x.Uuid.EqualsValue(y.Uuid);
|
||||
}
|
||||
public int GetHashCode (PwGroup obj)
|
||||
{
|
||||
return obj.Uuid.ToHexString().GetHashCode();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
158
src/keepass2android/PwGroupListAdapter.cs
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using KeePassLib;
|
||||
using keepass2android.view;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
public class PwGroupListAdapter : BaseAdapter
|
||||
{
|
||||
|
||||
private GroupBaseActivity mAct;
|
||||
private PwGroup mGroup;
|
||||
private List<PwGroup> groupsForViewing;
|
||||
private List<PwEntry> entriesForViewing;
|
||||
|
||||
private ISharedPreferences prefs;
|
||||
|
||||
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
||||
mAct = act;
|
||||
mGroup = group;
|
||||
prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
||||
|
||||
filterAndSort();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void NotifyDataSetChanged() {
|
||||
base.NotifyDataSetChanged();
|
||||
|
||||
filterAndSort();
|
||||
}
|
||||
|
||||
|
||||
public override void NotifyDataSetInvalidated() {
|
||||
base.NotifyDataSetInvalidated();
|
||||
|
||||
filterAndSort();
|
||||
}
|
||||
|
||||
private void filterAndSort() {
|
||||
entriesForViewing = new List<PwEntry>();
|
||||
|
||||
foreach (PwEntry entry in mGroup.Entries)
|
||||
{
|
||||
entriesForViewing.Add(entry);
|
||||
}
|
||||
|
||||
bool sortLists = prefs.GetBoolean(mAct.GetString(Resource.String.sort_key), mAct.Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||
if ( sortLists )
|
||||
{
|
||||
groupsForViewing = new List<PwGroup>(mGroup.Groups);
|
||||
groupsForViewing.Sort( (PwGroup x,PwGroup y) => { return String.Compare (x.Name, y.Name, true); });
|
||||
entriesForViewing.Sort( (PwEntry x, PwEntry y) =>
|
||||
{
|
||||
String nameX = x.Strings.ReadSafe(PwDefs.TitleField);
|
||||
String nameY = y.Strings.ReadSafe(PwDefs.TitleField);
|
||||
if (nameX.ToLower() != nameY.ToLower())
|
||||
return String.Compare (nameX,nameY,true);
|
||||
else
|
||||
return x.CreationTime.CompareTo(y.CreationTime);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
groupsForViewing = new List<PwGroup>(mGroup.Groups);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get{
|
||||
|
||||
return groupsForViewing.Count + entriesForViewing.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override Java.Lang.Object GetItem(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent) {
|
||||
int size = groupsForViewing.Count;
|
||||
|
||||
if ( position < size ) {
|
||||
return createGroupView(position, convertView);
|
||||
} else {
|
||||
return createEntryView(position - size, convertView);
|
||||
}
|
||||
}
|
||||
|
||||
private View createGroupView(int position, View convertView) {
|
||||
PwGroup g = groupsForViewing[position];
|
||||
PwGroupView gv;
|
||||
|
||||
if (convertView == null || !(convertView is PwGroupView)) {
|
||||
|
||||
gv = PwGroupView.getInstance(mAct, g);
|
||||
}
|
||||
else {
|
||||
gv = (PwGroupView) convertView;
|
||||
gv.convertView(g);
|
||||
|
||||
}
|
||||
|
||||
return gv;
|
||||
}
|
||||
|
||||
private PwEntryView createEntryView(int position, View convertView) {
|
||||
PwEntry entry = entriesForViewing[position];
|
||||
PwEntryView ev;
|
||||
|
||||
if (convertView == null || !(convertView is PwEntryView)) {
|
||||
ev = PwEntryView.getInstance(mAct, entry, position);
|
||||
}
|
||||
else {
|
||||
ev = (PwEntryView) convertView;
|
||||
ev.convertView(entry, position);
|
||||
}
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
49
src/keepass2android/PwUuidEqualityComparer.cs
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
class PwUuidEqualityComparer: IEqualityComparer<PwUuid>
|
||||
{
|
||||
#region IEqualityComparer implementation
|
||||
public bool Equals (PwUuid x, PwUuid y)
|
||||
{
|
||||
return x.EqualsValue(y);
|
||||
}
|
||||
public int GetHashCode (PwUuid obj)
|
||||
{
|
||||
return obj.ToHexString().GetHashCode();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
116
src/keepass2android/QuickUnlock.cs
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Content.PM;
|
||||
using KeePassLib.Keys;
|
||||
using Android.Preferences;
|
||||
using Android.Views.InputMethods;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")]
|
||||
public class QuickUnlock : LifecycleDebugActivity
|
||||
{
|
||||
IOConnectionInfo mIoc;
|
||||
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
|
||||
Intent i = Intent;
|
||||
mIoc = App.getDB().mIoc;
|
||||
|
||||
if (mIoc == null)
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetContentView(Resource.Layout.QuickUnlock);
|
||||
|
||||
((TextView)FindViewById(Resource.Id.qu_filename)).Text = mIoc.GetDisplayName();
|
||||
|
||||
|
||||
TextView txtLabel = (TextView)FindViewById(Resource.Id.QuickUnlock_label);
|
||||
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
int quickUnlockLength = App.getDB().QuickUnlockKeyLength;
|
||||
|
||||
txtLabel.Text = GetString(Resource.String.QuickUnlock_label, new Java.Lang.Object[]{quickUnlockLength});
|
||||
|
||||
EditText pwd= (EditText)FindViewById(Resource.Id.QuickUnlock_password);
|
||||
pwd.SetEms(quickUnlockLength);
|
||||
pwd.PostDelayed(() => {
|
||||
InputMethodManager keyboard = (InputMethodManager)GetSystemService(Context.InputMethodService);
|
||||
keyboard.ShowSoftInput(pwd, 0);
|
||||
}, 50);
|
||||
|
||||
SetResult(KeePass.EXIT_CHANGE_DB);
|
||||
|
||||
Button btnUnlock = (Button)FindViewById(Resource.Id.QuickUnlock_button);
|
||||
btnUnlock.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword));
|
||||
String password = kcpPassword.Password.ReadString();
|
||||
String expectedPasswordPart = password.Substring(Math.Max(0,password.Length-quickUnlockLength),Math.Min(password.Length, quickUnlockLength));
|
||||
if (pwd.Text == expectedPasswordPart)
|
||||
{
|
||||
SetResult(KeePass.EXIT_QUICK_UNLOCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetResult(KeePass.EXIT_FORCE_LOCK);
|
||||
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
||||
}
|
||||
Finish();
|
||||
};
|
||||
|
||||
Button btnLock = (Button)FindViewById(Resource.Id.QuickUnlock_buttonLock);
|
||||
btnLock.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
SetResult(KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB);
|
||||
Finish();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
|
||||
if ( ! App.getDB().Loaded ) {
|
||||
SetResult(KeePass.EXIT_CHANGE_DB);
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
src/keepass2android/Resources/AboutResources.txt
Normal file
@ -0,0 +1,44 @@
|
||||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.axml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.axml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called "R"
|
||||
(this is an Android convention) that contains the tokens for each one of the resources
|
||||
included. For example, for the above Resources layout, this is what the R class would expose:
|
||||
|
||||
public class R {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
|
||||
to reference the layout/main.axml file, or R.Strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
1796
src/keepass2android/Resources/Resource.designer.cs
generated
Normal file
BIN
src/keepass2android/Resources/drawable-hdpi/2_action_about.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic00.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic01.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic02.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic03.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic04.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic05.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic06.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic07.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic08.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic09.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic10.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic11.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic12.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic13.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic14.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic15.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic16.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic17.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic18.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic19.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic20.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic21.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic22.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic23.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic24.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic25.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic26.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic27.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic28.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic29.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic30.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic31.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic32.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic33.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic34.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic35.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic36.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic37.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic38.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
src/keepass2android/Resources/drawable-hdpi/ic39.png
Normal file
After Width: | Height: | Size: 5.7 KiB |