initial release 0.5.0 BETA

This commit is contained in:
PhilippC 2013-02-23 17:43:42 +01:00
parent 36c1df19d4
commit 19f7dcf26d
439 changed files with 19770 additions and 153 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/src/keepass2android/todos.cs
/src/keepass2android/obj
/src/keepass2android/bin
/src/KeePassLib2Android/bin

5
CONTRIBUTORS Normal file
View 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
View 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
View 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
View 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

View File

@ -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);

View File

@ -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" />

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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; }
}

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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(); }

View File

@ -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); }
}

View File

@ -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

View File

@ -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) { }

View File

@ -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,

View File

@ -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;

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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); }

View 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;
}
}
}

View 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;

View 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);
}
}
}

View 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;
}
}
}

View 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);
}
*/
}

View 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);
}
}
}

View 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);
}
}
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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();
}
}
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}
}

View 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();
}
}
}

View 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)
{
}
}
}

View 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");
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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");
}
}
}

View 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");
}
}
}

View 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);
}
}
}
}
}

View 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();});
}
}
}
}

View 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>

View 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("")]

View 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
}
}

View 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;
}
}
}

View 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
}
}

View 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;
}
}
}
}

View 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.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More