fix submodule

This commit is contained in:
Joe Mattiello
2023-03-01 13:17:09 -05:00
parent 686d1ab42a
commit 2d232fa702
468 changed files with 0 additions and 153638 deletions

12
.gitmodules vendored
View File

@@ -1,15 +1,3 @@
[submodule "Sources/libimobiledevice/dependencies/libimobiledevice"]
path = Sources/libimobiledevice/dependencies/libimobiledevice
url = https://github.com/libimobiledevice/libimobiledevice
[submodule "Sources/libimobiledevice/dependencies/libusbmuxd"]
path = Sources/libimobiledevice/dependencies/libusbmuxd
url = https://github.com/libimobiledevice/libusbmuxd.git
[submodule "Sources/libimobiledevice/dependencies/libplist"]
path = Sources/libimobiledevice/dependencies/libplist
url = https://github.com/libimobiledevice/libplist.git
[submodule "Sources/libimobiledevice/dependencies/libimobiledevice-glue"]
path = Sources/libimobiledevice/dependencies/libimobiledevice-glue
url = https://github.com/libimobiledevice/libimobiledevice-glue
[submodule "Sources/libfragmentzip"] [submodule "Sources/libfragmentzip"]
path = Sources/libfragmentzip/libfragmentzip-source path = Sources/libfragmentzip/libfragmentzip-source
url = https://github.com/SideStore/libfragmentzip.git url = https://github.com/SideStore/libfragmentzip.git

View File

@@ -1,164 +0,0 @@
name: build
on:
push:
schedule:
- cron: '0 0 1 * *'
jobs:
build-linux-ubuntu:
runs-on: ubuntu-latest
steps:
- name: install dependencies
run: |
#sudo apt-get install cython
- name: prepare environment
run: |
echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_${{env.target_triplet}}
repo: libimobiledevice/libplist
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
sudo cp -r extract/* /
sudo ldconfig
- uses: actions/checkout@v2
- name: autogen
run: ./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig LDFLAGS="-Wl,-rpath=/usr/local/lib"
- name: make
run: make
- name: make install
run: sudo make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice-glue.tar usr
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-glue-latest_${{env.target_triplet}}
path: libimobiledevice-glue.tar
build-macOS:
runs-on: macOS-latest
steps:
- name: install dependencies
run: |
if test -x "`which port`"; then
sudo port install libtool autoconf automake pkgconfig
else
brew install libtool autoconf automake pkgconfig
fi
shell: bash
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_macOS
repo: libimobiledevice/libplist
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
sudo cp -r extract/* /
- uses: actions/checkout@v2
- name: autogen
run: |
SDKDIR=`xcrun --sdk macosx --show-sdk-path`
TESTARCHS="arm64 x86_64"
USEARCHS=
for ARCH in $TESTARCHS; do
if echo "int main(int argc, char **argv) { return 0; }" |clang -arch $ARCH -o /dev/null -isysroot $SDKDIR -x c - 2>/dev/null; then
USEARCHS="$USEARCHS -arch $ARCH"
fi
done
export CFLAGS="$USEARCHS -isysroot $SDKDIR"
echo "Using CFLAGS: $CFLAGS"
./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
- name: make
run: make
- name: make install
run: sudo make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice-glue.tar usr
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-glue-latest_macOS
path: libimobiledevice-glue.tar
build-windows:
runs-on: windows-2019
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
include: [
{ msystem: MINGW64, arch: x86_64 },
{ msystem: MINGW32, arch: i686 }
]
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
release: false
update: false
install: >-
base-devel
git
mingw-w64-${{ matrix.arch }}-gcc
make
libtool
autoconf
automake-wrapper
- name: prepare environment
run: |
dest=`echo ${{ matrix.msystem }} |tr [:upper:] [:lower:]`
echo "dest=$dest" >> $GITHUB_ENV
echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_${{ matrix.arch }}-${{ env.dest }}
repo: libimobiledevice/libplist
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
cp -r extract/* /
- uses: actions/checkout@v2
- name: autogen
run: ./autogen.sh CC=gcc CXX=g++
- name: make
run: make
- name: make install
run: make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice-glue.tar ${{ env.dest }}
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-glue-latest_${{ matrix.arch }}-${{ env.dest }}
path: libimobiledevice-glue.tar

View File

@@ -1,39 +0,0 @@
# git-ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
*.[oa]
*~
*.po
*.lo
*.la
autom4te.cache/*
*.in
*/.deps/*
m4/*
swig/*
*.swp
*.patch
aclocal.m4
config.h
config.log
config.sub
config.guess
config.status
configure
depcomp
install-sh
compile
main
ltmain.sh
missing
mkinstalldirs
libtool
*Makefile
py-compile
stamp-h1
src/.libs
src/libimobiledevice-glue-1.0.pc
.idea/
.DS_Store
.vscode/

View File

@@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 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.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either
version 2.1 of the License, or (at your option) any later version.
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; 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.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -1,10 +0,0 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src include
EXTRA_DIST = \
README.md
indent:
indent -kr -ut -ts4 -l120 src/*.c src/*.h

View File

@@ -1,107 +0,0 @@
# libimobiledevice-glue
Library with common code used by the libraries and tools around the
**libimobiledevice** project.
![](https://github.com/libimobiledevice/libimobiledevice-glue/workflows/build/badge.svg)
## Features
The main functionality provided by this library are **socket** helper
functions and a platform independent **thread/mutex** implementation.
Besides that it comes with a number of string, file, and plist helper
functions, as well as some other commonly used code that was originally
duplicated in the dedicated projects.
Test on Linux, macOS, Windows.
## Projects using this library
- [libusbmuxd](https://github.com/libimobiledevice/libusbmuxd)
- [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)
- [usbmuxd](https://github.com/libimobiledevice/usbmuxd)
- [libirecovery](https://github.com/libimobiledevice/libirecovery)
- [idevicerestore](https://github.com/libimobiledevice/idevicerestore)
## Installation / Getting started
### Debian / Ubuntu Linux
First install all required dependencies and build tools:
```shell
sudo apt-get install \
build-essential \
pkg-config \
checkinstall \
git \
autoconf \
automake \
libtool-bin \
libplist-dev \
```
Then clone the actual project repository:
```shell
git clone https://github.com/libimobiledevice/libimobiledevice-glue.git
cd libimobiledevice-glue
```
Now you can build and install it:
```shell
./autogen.sh
make
sudo make install
```
If you require a custom prefix or other option being passed to `./configure`
you can pass them directly to `./autogen.sh` like this:
```bash
./autogen.sh --prefix=/opt/local
make
sudo make install
```
## Usage
This library is directly used by libusbmuxd, libimobiledevice, etc., so there
is no need to do anything in particular.
## Contributing
We welcome contributions from anyone and are grateful for every pull request!
If you'd like to contribute, please fork the `master` branch, change, commit and
send a pull request for review. Once approved it can be merged into the main
code base.
If you plan to contribute larger changes or a major refactoring, please create a
ticket first to discuss the idea upfront to ensure less effort for everyone.
Please make sure your contribution adheres to:
* Try to follow the code style of the project
* Commit messages should describe the change well without being too short
* Try to split larger changes into individual commits of a common domain
## Links
* Homepage: https://libimobiledevice.org/
* Repository: https://git.libimobiledevice.org/libimobiledevice-glue.git
* Repository (Mirror): https://github.com/libimobiledevice/libimobiledevice-glue.git
* Issue Tracker: https://github.com/libimobiledevice/libimobiledevice-glue/issues
* Mailing List: https://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel
* Twitter: https://twitter.com/libimobiledev
## License
This library and utilities are licensed under the [GNU Lesser General Public License v2.1](https://www.gnu.org/licenses/lgpl-2.1.en.html),
also included in the repository in the `COPYING` file.
## Credits
Apple, iPhone, iPad, iPod, iPod Touch, Apple TV, Apple Watch, Mac, iOS,
iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc.
This project is an independent software and has not been authorized, sponsored,
or otherwise approved by Apple Inc.
README Updated on: 2022-04-04

View File

@@ -1,26 +0,0 @@
#!/bin/sh
olddir=`pwd`
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
(
cd "$srcdir"
gprefix=`which glibtoolize 2>&1 >/dev/null`
if [ $? -eq 0 ]; then
glibtoolize --force
else
libtoolize --force
fi
aclocal -I m4
autoheader
automake --add-missing
autoconf
cd "$olddir"
)
if [ -z "$NOCONFIGURE" ]; then
$srcdir/configure "$@"
fi

View File

@@ -1,136 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.68)
AC_INIT([libimobiledevice-glue], [1.0.0], [https://github.com/libimobiledevice/libimobiledevice-glue/issues],, [https://libimobiledevice.org])
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip check-news])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
AC_CONFIG_SRCDIR([src/])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
dnl libtool versioning
# +1 : 0 : +1 == adds new functions to the interface
# +1 : 0 : 0 == changes or removes functions (changes include both
# changes to the signature and the semantic)
# ? :+1 : ? == just internal changes
# CURRENT : REVISION : AGE
LIBIMOBILEDEVICE_GLUE_SO_VERSION=0:0:0
dnl Minimum package versions
LIBPLIST_VERSION=2.2.0
AC_SUBST(LIBIMOBILEDEVICE_GLUE_SO_VERSION)
AC_SUBST(LIBPLIST_VERSION)
# Checks for programs.
AC_PROG_CC
#AC_PROG_CXX
AM_PROG_CC_C_O
LT_INIT
# Checks for libraries.
PKG_CHECK_MODULES(libplist, libplist-2.0 >= $LIBPLIST_VERSION)
# Checks for header files.
AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_CHECK_FUNCS([asprintf strcasecmp strdup strerror strndup stpcpy vasprintf getifaddrs])
AC_CHECK_HEADER(endian.h, [ac_cv_have_endian_h="yes"], [ac_cv_have_endian_h="no"])
if test "x$ac_cv_have_endian_h" = "xno"; then
AC_DEFINE(__LITTLE_ENDIAN,1234,[little endian])
AC_DEFINE(__BIG_ENDIAN,4321,[big endian])
AC_C_BIGENDIAN([ac_cv_c_bigendian="yes"], [ac_cv_c_bigendian="no"], [], [])
if test "x$ac_cv_c_bigendian" = "xyes"; then
AC_DEFINE(__BYTE_ORDER,4321,[big endian byte order])
else
AC_DEFINE(__BYTE_ORDER,1234,[little endian byte order])
fi
fi
# Check for operating system
AC_MSG_CHECKING([for platform-specific build settings])
case ${host_os} in
*mingw32*|*cygwin*)
AC_MSG_RESULT([${host_os}])
win32=true
AC_DEFINE(WINVER, 0x0501, [minimum Windows version])
;;
darwin*)
AC_MSG_RESULT([${host_os}])
AX_PTHREAD([], [AC_MSG_ERROR([pthread is required to build $PACKAGE])])
AC_CHECK_FUNCS([pthread_once pthread_cancel])
;;
*)
AC_MSG_RESULT([${host_os}])
AX_PTHREAD([], [AC_MSG_ERROR([pthread is required to build $PACKAGE_NAME])])
AC_CHECK_FUNC(pthread_cancel, [AC_DEFINE(HAVE_PTHREAD_CANCEL)], [
AC_CHECK_LIB(pthread, [pthread_cancel],[AC_DEFINE(HAVE_PTHREAD_CANCEL)])
])
AC_CHECK_FUNC(pthread_once, [AC_DEFINE(HAVE_PTHREAD_ONCE)], [
AC_CHECK_LIB(pthread, [pthread_once], [], [AC_MSG_ERROR([pthread with pthread_once required to build $PACKAGE_NAME])])
])
;;
esac
AM_CONDITIONAL(WIN32, test x$win32 = xtrue)
# Check if the C compiler supports __attribute__((constructor))
AC_CACHE_CHECK([wether the C compiler supports constructor/destructor attributes],
ac_cv_attribute_constructor, [
ac_cv_attribute_constructor=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
static void __attribute__((constructor)) test_constructor(void) {
}
static void __attribute__((destructor)) test_destructor(void) {
}
]], [])],
[ac_cv_attribute_constructor=yes]
)]
)
if test "$ac_cv_attribute_constructor" = "yes"; then
AC_DEFINE(HAVE_ATTRIBUTE_CONSTRUCTOR, 1, [Define if the C compiler supports constructor/destructor attributes])
fi
AC_CHECK_MEMBER(struct dirent.d_type, AC_DEFINE(HAVE_DIRENT_D_TYPE, 1, [define if struct dirent has member d_type]),, [#include <dirent.h>])
AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter -fsigned-char -fvisibility=hidden")
AC_SUBST(GLOBAL_CFLAGS)
case "$GLOBAL_CFLAGS" in
*-fvisibility=hidden*)
AC_DEFINE([HAVE_FVISIBILITY], [1], [Define if compiled with -fvisibility=hidden])
esac
# check for large file support
AC_SYS_LARGEFILE
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_CONFIG_FILES([
Makefile
src/Makefile
src/libimobiledevice-glue-1.0.pc
include/Makefile
])
AC_OUTPUT
echo "
Configuration for $PACKAGE $VERSION:
-------------------------------------------
Install prefix: .........: $prefix
Now type 'make' to build $PACKAGE $VERSION,
and then 'make install' for installation.
"

View File

@@ -1,12 +0,0 @@
EXTRA_DIST = \
endianness.h
nobase_include_HEADERS = \
libimobiledevice-glue/socket.h \
libimobiledevice-glue/thread.h \
libimobiledevice-glue/utils.h \
libimobiledevice-glue/collection.h \
libimobiledevice-glue/termcolors.h \
libimobiledevice-glue/cbuf.h \
libimobiledevice-glue/opack.h \
libimobiledevice-glue/tlv.h

View File

@@ -1,123 +0,0 @@
#ifndef ENDIANNESS_H
#define ENDIANNESS_H
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif
#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif
#ifndef __BYTE_ORDER
#ifdef __LITTLE_ENDIAN__
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#ifdef __BIG_ENDIAN__
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
#endif
#ifndef be16toh
#if __BYTE_ORDER == __BIG_ENDIAN
#define be16toh(x) (x)
#else
#define be16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#endif
#endif
#ifndef htobe16
#define htobe16 be16toh
#endif
#ifndef le16toh
#if __BYTE_ORDER == __BIG_ENDIAN
#define le16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#else
#define le16toh(x) (x)
#endif
#endif
#ifndef htole16
#define htole16 le16toh
#endif
#ifndef __bswap_32
#define __bswap_32(x) ((((x) & 0xFF000000) >> 24) \
| (((x) & 0x00FF0000) >> 8) \
| (((x) & 0x0000FF00) << 8) \
| (((x) & 0x000000FF) << 24))
#endif
#ifndef be32toh
#if __BYTE_ORDER == __BIG_ENDIAN
#define be32toh(x) (x)
#else
#define be32toh(x) __bswap_32(x)
#endif
#endif
#ifndef htobe32
#define htobe32 be32toh
#endif
#ifndef le32toh
#if __BYTE_ORDER == __BIG_ENDIAN
#define le32toh(x) __bswap_32(x)
#else
#define le32toh(x) (x)
#endif
#endif
#ifndef htole32
#define htole32 le32toh
#endif
#ifndef __bswap_64
#define __bswap_64(x) ((((x) & 0xFF00000000000000ull) >> 56) \
| (((x) & 0x00FF000000000000ull) >> 40) \
| (((x) & 0x0000FF0000000000ull) >> 24) \
| (((x) & 0x000000FF00000000ull) >> 8) \
| (((x) & 0x00000000FF000000ull) << 8) \
| (((x) & 0x0000000000FF0000ull) << 24) \
| (((x) & 0x000000000000FF00ull) << 40) \
| (((x) & 0x00000000000000FFull) << 56))
#endif
#ifndef htobe64
#if __BYTE_ORDER == __BIG_ENDIAN
#define htobe64(x) (x)
#else
#define htobe64(x) __bswap_64(x)
#endif
#endif
#ifndef be64toh
#define be64toh htobe64
#endif
#ifndef le64toh
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le64toh(x) (x)
#else
#define le64toh(x) __bswap_64(x)
#endif
#endif
#ifndef htole64
#define htole64 le64toh
#endif
#if (defined(__BIG_ENDIAN__) \
&& !defined(__FLOAT_WORD_ORDER__)) \
|| (defined(__FLOAT_WORD_ORDER__) \
&& __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
#define float_bswap64(x) __bswap_64(x)
#define float_bswap32(x) __bswap_32(x)
#else
#define float_bswap64(x) (x)
#define float_bswap32(x) (x)
#endif
#endif /* ENDIANNESS_H */

View File

@@ -1,35 +0,0 @@
/*
* cbuf.h
* Simple char buffer implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CBUF_H
#define __CBUF_H
struct char_buf {
unsigned char* data;
unsigned int length;
unsigned int capacity;
};
struct char_buf* char_buf_new();
void char_buf_free(struct char_buf* cbuf);
void char_buf_append(struct char_buf* cbuf, unsigned int length, unsigned char* data);
#endif /* __CBUF_H */

View File

@@ -1,52 +0,0 @@
/*
* collection.h
*
* Copyright (C) 2009 Hector Martin <hector@marcansoft.com>
* Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COLLECTION_H
#define COLLECTION_H
struct collection {
void **list;
int capacity;
};
void collection_init(struct collection *col);
void collection_add(struct collection *col, void *element);
int collection_remove(struct collection *col, void *element);
int collection_count(struct collection *col);
void collection_free(struct collection *col);
void collection_copy(struct collection *dest, struct collection *src);
#define MERGE_(a,b) a ## _ ## b
#define LABEL_(a,b) MERGE_(a, b)
#define UNIQUE_VAR(a) LABEL_(a, __LINE__)
#define FOREACH(var, col) \
do { \
int UNIQUE_VAR(_iter); \
for(UNIQUE_VAR(_iter)=0; UNIQUE_VAR(_iter)<(col)->capacity; UNIQUE_VAR(_iter)++) { \
if(!(col)->list[UNIQUE_VAR(_iter)]) continue; \
var = (col)->list[UNIQUE_VAR(_iter)];
#define ENDFOREACH \
} \
} while(0);
#endif

View File

@@ -1,29 +0,0 @@
/*
* opack.h
* "opack" format encoder/decoder implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __OPACK_H
#define __OPACK_H
#include <plist/plist.h>
void opack_encode_from_plist(plist_t plist, unsigned char** out, unsigned int* out_len);
int opack_decode_to_plist(unsigned char* buf, unsigned int buf_len, plist_t* plist_out);
#endif /* __OPACK_H */

View File

@@ -1,70 +0,0 @@
/*
* socket.h
*
* Copyright (C) 2012-2020 Nikias Bassen <nikias@gmx.li>
* Copyright (C) 2012 Martin Szulecki <m.szulecki@libimobiledevice.org>
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SOCKET_SOCKET_H
#define SOCKET_SOCKET_H
#include <stdlib.h>
#include <stdint.h>
enum fd_mode {
FDM_READ,
FDM_WRITE,
FDM_EXCEPT
};
typedef enum fd_mode fd_mode;
#ifdef WIN32
#include <winsock2.h>
#define SHUT_RD SD_READ
#define SHUT_WR SD_WRITE
#define SHUT_RDWR SD_BOTH
#else
#include <sys/socket.h>
#endif
#ifndef WIN32
int socket_create_unix(const char *filename);
int socket_connect_unix(const char *filename);
#endif
int socket_create(const char *addr, uint16_t port);
int socket_connect_addr(struct sockaddr *addr, uint16_t port);
int socket_connect(const char *addr, uint16_t port);
int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout);
int socket_accept(int fd, uint16_t port);
int socket_shutdown(int fd, int how);
int socket_close(int fd);
int socket_receive(int fd, void *data, size_t length);
int socket_peek(int fd, void *data, size_t length);
int socket_receive_timeout(int fd, void *data, size_t length, int flags, unsigned int timeout);
int socket_send(int fd, void *data, size_t length);
int socket_get_socket_port(int fd, uint16_t *port);
void socket_set_verbose(int level);
const char *socket_addr_to_string(struct sockaddr *addr, char *addr_out, size_t addr_out_size);
int get_primary_mac_address(unsigned char mac_addr_buf[6]);
#endif /* SOCKET_SOCKET_H */

View File

@@ -1,87 +0,0 @@
/*
* termcolors.h
*
* Copyright (c) 2020-2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef TERMCOLORS_H
#define TERMCOLORS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdarg.h>
#include <stdio.h>
#define COLOR_RESET "\e[m"
#define STYLE_NORMAL "\e[0m"
#define STYLE_BRIGHT "\e[1m"
#define STYLE_DARK "\e[2m"
#define FG_BLACK "\e[0;30m"
#define FG_DARK_GRAY "\e[1;30m"
#define FG_RED "\e[0;31m"
#define FG_BRIGHT_RED "\e[1;31m"
#define FG_DARK_RED "\e[2;31m"
#define FG_GREEN "\e[0;32m"
#define FG_BRIGHT_GREEN "\e[1;32m"
#define FG_DARK_GREEN "\e[2;32m"
#define FG_YELLOW "\e[0;33m"
#define FG_BRIGHT_YELLOW "\e[1;33m"
#define FG_DARK_YELLOW "\e[2;33m"
#define FG_BLUE "\e[0;34m"
#define FG_BRIGHT_BLUE "\e[1;34m"
#define FG_DARK_BLUE "\e[2;34m"
#define FG_MAGENTA "\e[0;35m"
#define FG_BRIGHT_MAGENTA "\e[1;35m"
#define FG_DARK_MAGENTA "\e[2;35m"
#define FG_CYAN "\e[0;36m"
#define FG_BRIGHT_CYAN "\e[1;36m"
#define FG_DARK_CYAN "\e[2;36m"
#define FG_LIGHT_GRAY "\e[0;37m"
#define FG_WHITE "\e[1;37m"
#define FG_GRAY "\e[2;37m"
#define FG_DEFAULT "\e[39m"
#define BG_BLACK "\e[40m"
#define BG_GRAY "\e[100m"
#define BG_RED "\e[41m"
#define BG_BRIGHT_RED "\e[101m"
#define BG_GREEN "\e[42m"
#define BG_BRIGHT_GREEN "\e[102m"
#define BG_YELLOW "\e[43m"
#define BG_BRIGHT_YELLOW "\e[103m"
#define BG_BLUE "\e[44m"
#define BG_BRIGHT_BLUE "\e[104m"
#define BG_MAGENTA "\e[45m"
#define BG_BRIGHT_MAGENTA "\e[105m"
#define BG_CYAN "\e[46m"
#define BG_BRIGHT_CYAN "\e[106m"
#define BG_LIGHT_GRAY "\e[47m"
#define BG_WHITE "\e[107m"
#define BG_DEFAULT "\e[49m"
/* automatically called by library constructor */
void term_colors_init();
/* enable / disable terminal colors */
void term_colors_set_enabled(int en);
/* color-aware *printf variants */
int cprintf(const char* fmt, ...);
int cfprintf(FILE* stream, const char* fmt, ...);
int cvfprintf(FILE* stream, const char* fmt, va_list vargs);
#endif

View File

@@ -1,87 +0,0 @@
/*
* thread.h
*
* Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2012 Martin Szulecki, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __THREAD_H
#define __THREAD_H
#include <stddef.h>
#ifdef WIN32
#include <windows.h>
typedef HANDLE THREAD_T;
typedef CRITICAL_SECTION mutex_t;
typedef struct {
HANDLE sem;
} cond_t;
typedef volatile struct {
LONG lock;
int state;
} thread_once_t;
#define THREAD_ONCE_INIT {0, 0}
#define THREAD_ID GetCurrentThreadId()
#define THREAD_T_NULL (THREAD_T)NULL
#else
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
typedef pthread_t THREAD_T;
typedef pthread_mutex_t mutex_t;
typedef pthread_cond_t cond_t;
typedef pthread_once_t thread_once_t;
#define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
#define THREAD_ID pthread_self()
#define THREAD_T_NULL (THREAD_T)NULL
#endif
typedef void* (*thread_func_t)(void* data);
int thread_new(THREAD_T* thread, thread_func_t thread_func, void* data);
void thread_detach(THREAD_T thread);
void thread_free(THREAD_T thread);
int thread_join(THREAD_T thread);
int thread_alive(THREAD_T thread);
int thread_cancel(THREAD_T thread);
#ifdef WIN32
#undef HAVE_THREAD_CLEANUP
#else
#ifdef HAVE_PTHREAD_CANCEL
#define HAVE_THREAD_CLEANUP 1
#define thread_cleanup_push(routine, arg) pthread_cleanup_push(routine, arg)
#define thread_cleanup_pop(execute) pthread_cleanup_pop(execute)
#endif
#endif
void mutex_init(mutex_t* mutex);
void mutex_destroy(mutex_t* mutex);
void mutex_lock(mutex_t* mutex);
void mutex_unlock(mutex_t* mutex);
void thread_once(thread_once_t *once_control, void (*init_routine)(void));
void cond_init(cond_t* cond);
void cond_destroy(cond_t* cond);
int cond_signal(cond_t* cond);
int cond_wait(cond_t* cond, mutex_t* mutex);
int cond_wait_timeout(cond_t* cond, mutex_t* mutex, unsigned int timeout_ms);
#endif

View File

@@ -1,42 +0,0 @@
/*
* tlv.h
* Simple TLV implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __TLV_H
#define __TLV_H
#include <stdint.h>
struct tlv_buf {
unsigned char* data;
unsigned int length;
unsigned int capacity;
};
typedef struct tlv_buf* tlv_buf_t;
tlv_buf_t tlv_buf_new();
void tlv_buf_free(tlv_buf_t tlv);
void tlv_buf_append(tlv_buf_t tlv, uint8_t tag, unsigned int length, void* data);
unsigned char* tlv_get_data_ptr(const void* tlv_data, void* tlv_end, uint8_t tag, uint8_t* length);
int tlv_data_get_uint(const void* tlv_data, unsigned int tlv_length, uint8_t tag, uint64_t* value);
int tlv_data_get_uint8(const void* tlv_data, unsigned int tlv_length, uint8_t tag, uint8_t* value);
int tlv_data_copy_data(const void* tlv_data, unsigned int tlv_length, uint8_t tag, void** out, unsigned int* out_len);
#endif /* __TLV_H */

View File

@@ -1,62 +0,0 @@
/*
* utils.h
* Miscellaneous utilities for string manipulation,
* file I/O and plist helper.
*
* Copyright (c) 2014-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2013-2014 Martin Szulecki, All Rights Reserved.
* Copyright (c) 2013 Federico Mena Quintero
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __UTILS_H
#define __UTILS_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <plist/plist.h>
#define MAC_EPOCH 978307200
char *string_concat(const char *str, ...);
char *string_append(char *str, ...);
char *string_build_path(const char *elem, ...);
char *string_format_size(uint64_t size);
char *string_toupper(char *str);
char *generate_uuid(void);
int buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length);
int buffer_write_to_filename(const char *filename, const char *buffer, uint64_t length);
enum plist_format_t {
PLIST_FORMAT_XML,
PLIST_FORMAT_BINARY
};
int plist_read_from_filename(plist_t *plist, const char *filename);
int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format);
void plist_print_to_stream(plist_t plist, FILE* stream);
void plist_print_to_stream_with_indentation(plist_t plist, FILE* stream, unsigned int indentation);
#endif

View File

@@ -1,28 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
AM_CFLAGS = $(GLOBAL_CFLAGS) $(PTHREAD_CFLAGS) $(libplist_CFLAGS)
AM_LDFLAGS = $(PTHREAD_LIBS) $(libplist_LIBS)
lib_LTLIBRARIES = libimobiledevice-glue-1.0.la
libimobiledevice_glue_1_0_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBIMOBILEDEVICE_GLUE_SO_VERSION) -no-undefined
libimobiledevice_glue_1_0_la_LIBADD =
libimobiledevice_glue_1_0_la_SOURCES = \
glue.c \
socket.c \
thread.c \
utils.c \
collection.c \
termcolors.c \
cbuf.c \
opack.c \
tlv.c \
common.h
if WIN32
libimobiledevice_glue_1_0_la_LDFLAGS += -avoid-version -static-libgcc
libimobiledevice_glue_1_0_la_LIBADD += -lws2_32 -lIphlpapi
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libimobiledevice-glue-1.0.pc

View File

@@ -1,67 +0,0 @@
/*
* cbuf.c
* Simple char buffer implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
#include "libimobiledevice-glue/cbuf.h"
LIBIMOBILEDEVICE_GLUE_API struct char_buf* char_buf_new()
{
struct char_buf* cbuf = (struct char_buf*)malloc(sizeof(struct char_buf));
cbuf->capacity = 256;
cbuf->length = 0;
cbuf->data = (unsigned char*)malloc(cbuf->capacity);
return cbuf;
}
LIBIMOBILEDEVICE_GLUE_API void char_buf_free(struct char_buf* cbuf)
{
if (cbuf) {
free(cbuf->data);
free(cbuf);
}
}
LIBIMOBILEDEVICE_GLUE_API void char_buf_append(struct char_buf* cbuf, unsigned int length, unsigned char* data)
{
if (!cbuf || !cbuf->data) {
return;
}
if (cbuf->length + length > cbuf->capacity) {
unsigned int newcapacity = cbuf->capacity + ((length / 256) + 1) * 256;
unsigned char* newdata = realloc(cbuf->data, newcapacity);
if (!newdata) {
fprintf(stderr, "%s: ERROR: Failed to realloc\n", __func__);
return;
}
cbuf->data = newdata;
cbuf->capacity = newcapacity;
}
memcpy(cbuf->data + cbuf->length, data, length);
cbuf->length += length;
}

View File

@@ -1,101 +0,0 @@
/*
* collection.c
*
* Copyright (C) 2009 Hector Martin <hector@marcansoft.com>
* Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
#include "libimobiledevice-glue/collection.h"
#undef NDEBUG // we need to make sure we still get assertions because we can't handle memory allocation errors
#include <assert.h>
#define INIT_NULL(addr, count) { unsigned int i_ = 0; for (i_ = 0; i_ < (count); i_++) ((void**)(addr))[i_] = NULL; }
#define CAPACITY_STEP 8
LIBIMOBILEDEVICE_GLUE_API void collection_init(struct collection *col)
{
col->list = malloc(sizeof(void *) * CAPACITY_STEP);
assert(col->list);
INIT_NULL(col->list, CAPACITY_STEP);
col->capacity = CAPACITY_STEP;
}
LIBIMOBILEDEVICE_GLUE_API void collection_free(struct collection *col)
{
free(col->list);
col->list = NULL;
col->capacity = 0;
}
LIBIMOBILEDEVICE_GLUE_API void collection_add(struct collection *col, void *element)
{
int i;
for(i=0; i<col->capacity; i++) {
if(!col->list[i]) {
col->list[i] = element;
return;
}
}
void **newlist = realloc(col->list, sizeof(void*) * (col->capacity + CAPACITY_STEP));
assert(newlist);
col->list = newlist;
INIT_NULL(&col->list[col->capacity], CAPACITY_STEP);
col->list[col->capacity] = element;
col->capacity += CAPACITY_STEP;
}
LIBIMOBILEDEVICE_GLUE_API int collection_remove(struct collection *col, void *element)
{
int i;
for(i=0; i<col->capacity; i++) {
if(col->list[i] == element) {
col->list[i] = NULL;
return 0;
}
}
fprintf(stderr, "%s: WARNING: element %p not present in collection %p (cap %d)", __func__, element, col, col->capacity);
return -1;
}
LIBIMOBILEDEVICE_GLUE_API int collection_count(struct collection *col)
{
int i, cnt = 0;
for(i=0; i<col->capacity; i++) {
if(col->list[i])
cnt++;
}
return cnt;
}
LIBIMOBILEDEVICE_GLUE_API void collection_copy(struct collection *dest, struct collection *src)
{
if (!dest || !src) return;
dest->capacity = src->capacity;
dest->list = malloc(sizeof(void*) * src->capacity);
memcpy(dest->list, src->list, sizeof(void*) * src->capacity);
}

View File

@@ -1,38 +0,0 @@
/*
* common.h
*
* Copyright (c) 2020 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __COMMON_H
#define __COMMON_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WIN32
#define LIBIMOBILEDEVICE_GLUE_API __declspec( dllexport )
#else
#ifdef HAVE_FVISIBILITY
#define LIBIMOBILEDEVICE_GLUE_API __attribute__((visibility("default")))
#else
#define LIBIMOBILEDEVICE_GLUE_API
#endif
#endif
#endif

View File

@@ -1,80 +0,0 @@
/*
* glue.c
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include "common.h"
#include "libimobiledevice-glue/thread.h"
extern void term_colors_init();
static void internal_glue_init(void)
{
term_colors_init();
}
static void internal_glue_deinit(void)
{
}
static thread_once_t init_once = THREAD_ONCE_INIT;
static thread_once_t deinit_once = THREAD_ONCE_INIT;
#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR
#if defined(__llvm__) || defined(__GNUC__)
#define HAVE_ATTRIBUTE_CONSTRUCTOR
#endif
#endif
#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR
static void __attribute__((constructor)) limd_glue_initialize(void)
{
thread_once(&init_once, internal_glue_init);
}
static void __attribute__((destructor)) limd_glue_deinitialize(void)
{
thread_once(&deinit_once, internal_glue_deinit);
}
#elif defined(WIN32)
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
thread_once(&init_once, internal_glue_init);
break;
case DLL_PROCESS_DETACH:
thread_once(&deinit_once, internal_glue_deinit);
break;
default:
break;
}
return 1;
}
#else
#warning No compiler support for constructor/destructor attributes, some features might not be available.
#endif

View File

@@ -1,476 +0,0 @@
/*
* opack.c
* "opack" format encoder/decoder implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
#include "libimobiledevice-glue/cbuf.h"
#include "libimobiledevice-glue/opack.h"
#include "endianness.h"
#define MAC_EPOCH 978307200
static void opack_encode_node(plist_t node, struct char_buf* cbuf)
{
plist_type type = plist_get_node_type(node);
switch (type) {
case PLIST_DICT: {
uint32_t count = plist_dict_get_size(node);
uint8_t blen = 0xEF;
if (count < 15)
blen = (uint8_t)count-32;
char_buf_append(cbuf, 1, &blen);
plist_dict_iter iter = NULL;
plist_dict_new_iter(node, &iter);
if (iter) {
plist_t sub = NULL;
do {
sub = NULL;
plist_dict_next_item(node, iter, NULL, &sub);
if (sub) {
plist_t key = plist_dict_item_get_key(sub);
opack_encode_node(key, cbuf);
opack_encode_node(sub, cbuf);
}
} while (sub);
free(iter);
if (count > 14) {
uint8_t term = 0x03;
char_buf_append(cbuf, 1, &term);
}
}
} break;
case PLIST_ARRAY: {
uint32_t count = plist_array_get_size(node);
uint8_t blen = 0xDF;
if (count < 15)
blen = (uint8_t)(count-48);
char_buf_append(cbuf, 1, &blen);
plist_array_iter iter = NULL;
plist_array_new_iter(node, &iter);
if (iter) {
plist_t sub = NULL;
do {
sub = NULL;
plist_array_next_item(node, iter, &sub);
if (sub) {
opack_encode_node(sub, cbuf);
}
} while (sub);
free(iter);
if (count > 14) {
uint8_t term = 0x03;
char_buf_append(cbuf, 1, &term);
}
}
} break;
case PLIST_BOOLEAN: {
uint8_t bval = 2 - plist_bool_val_is_true(node);
char_buf_append(cbuf, 1, &bval);
} break;
case PLIST_UINT: {
uint64_t u64val = 0;
plist_get_uint_val(node, &u64val);
if ((uint8_t)u64val == u64val) {
uint8_t u8val = (uint8_t)u64val;
if (u8val > 0x27) {
uint8_t blen = 0x30;
char_buf_append(cbuf, 1, &blen);
char_buf_append(cbuf, 1, &u8val);
} else {
u8val += 8;
char_buf_append(cbuf, 1, &u8val);
}
} else if ((uint32_t)u64val == u64val) {
uint8_t blen = 0x32;
char_buf_append(cbuf, 1, &blen);
uint32_t u32val = (uint32_t)u64val;
u32val = htole32(u32val);
char_buf_append(cbuf, 4, (unsigned char*)&u32val);
} else {
uint8_t blen = 0x33;
char_buf_append(cbuf, 1, &blen);
u64val = htole64(u64val);
char_buf_append(cbuf, 8, (unsigned char*)&u64val);
}
} break;
case PLIST_REAL: {
double dval = 0;
plist_get_real_val(node, &dval);
if ((float)dval == dval) {
float fval = (float)dval;
uint32_t u32val = 0;
memcpy(&u32val, &fval, 4);
u32val = float_bswap32(u32val);
uint8_t blen = 0x35;
char_buf_append(cbuf, 1, &blen);
char_buf_append(cbuf, 4, (unsigned char*)&u32val);
} else {
uint64_t u64val = 0;
memcpy(&u64val, &dval, 8);
u64val = float_bswap64(u64val);
uint8_t blen = 0x36;
char_buf_append(cbuf, 1, &blen);
char_buf_append(cbuf, 8, (unsigned char*)&u64val);
}
} break;
case PLIST_DATE: {
int32_t sec = 0;
int32_t usec = 0;
plist_get_date_val(node, &sec, &usec);
time_t tsec = sec;
tsec -= MAC_EPOCH;
double dval = (double)tsec + ((double)usec / 1000000);
uint8_t blen = 0x06;
char_buf_append(cbuf, 1, &blen);
uint64_t u64val = 0;
memcpy(&u64val, &dval, 8);
u64val = float_bswap64(u64val);
char_buf_append(cbuf, 8, (unsigned char*)&u64val);
} break;
case PLIST_STRING:
case PLIST_KEY: {
uint64_t len = 0;
char* str = NULL;
if (type == PLIST_KEY) {
plist_get_key_val(node, &str);
len = strlen(str);
} else {
str = (char*)plist_get_string_ptr(node, &len);
}
if (len > 0x20) {
if (len > 0xFF) {
if (len > 0xFFFF) {
if (len >> 32) {
uint8_t blen = 0x64;
char_buf_append(cbuf, 1, &blen);
uint64_t u64val = htole64(len);
char_buf_append(cbuf, 8, (unsigned char*)&u64val);
} else {
uint8_t blen = 0x63;
char_buf_append(cbuf, 1, &blen);
uint32_t u32val = htole32((uint32_t)len);
char_buf_append(cbuf, 4, (unsigned char*)&u32val);
}
} else {
uint8_t blen = 0x62;
char_buf_append(cbuf, 1, &blen);
uint16_t u16val = htole16((uint16_t)len);
char_buf_append(cbuf, 2, (unsigned char*)&u16val);
}
} else {
uint8_t blen = 0x61;
char_buf_append(cbuf, 1, &blen);
char_buf_append(cbuf, 1, (unsigned char*)&len);
}
} else {
uint8_t blen = 0x40 + len;
char_buf_append(cbuf, 1, &blen);
}
char_buf_append(cbuf, len, (unsigned char*)str);
if (type == PLIST_KEY) {
free(str);
}
} break;
case PLIST_DATA: {
uint64_t len = 0;
const char* data = plist_get_data_ptr(node, &len);
if (len > 0x20) {
if (len > 0xFF) {
if (len > 0xFFFF) {
if (len >> 32) {
uint8_t blen = 0x94;
char_buf_append(cbuf, 1, &blen);
uint32_t u64val = htole64(len);
char_buf_append(cbuf, 8, (unsigned char*)&u64val);
} else {
uint8_t blen = 0x93;
char_buf_append(cbuf, 1, &blen);
uint32_t u32val = htole32((uint32_t)len);
char_buf_append(cbuf, 4, (unsigned char*)&u32val);
}
} else {
uint8_t blen = 0x92;
char_buf_append(cbuf, 1, &blen);
uint16_t u16val = htole16((uint16_t)len);
char_buf_append(cbuf, 2, (unsigned char*)&u16val);
}
} else {
uint8_t blen = 0x91;
char_buf_append(cbuf, 1, &blen);
char_buf_append(cbuf, 1, (unsigned char*)&len);
}
} else {
uint8_t blen = 0x70 + len;
char_buf_append(cbuf, 1, &blen);
}
char_buf_append(cbuf, len, (unsigned char*)data);
} break;
default:
fprintf(stderr, "%s: ERROR: Unsupported data type in plist\n", __func__);
break;
}
}
LIBIMOBILEDEVICE_GLUE_API void opack_encode_from_plist(plist_t plist, unsigned char** out, unsigned int* out_len)
{
if (!plist || !out || !out_len) {
return;
}
struct char_buf* cbuf = char_buf_new();
opack_encode_node(plist, cbuf);
*out = cbuf->data;
*out_len = cbuf->length;
cbuf->data = NULL;
char_buf_free(cbuf);
}
static int opack_decode_obj(unsigned char** p, unsigned char* end, plist_t* plist_out, uint32_t level)
{
uint8_t type = **p;
if (type == 0x02) {
/* bool: false */
*plist_out = plist_new_bool(0);
(*p)++;
return 0;
} else if (type == 0x01) {
/* bool: true */
*plist_out = plist_new_bool(1);
(*p)++;
return 0;
} else if (type == 0x03) {
/* NULL / structured type child node terminator */
(*p)++;
return -2;
} else if (type == 0x06) {
/* date type */
(*p)++;
double value = *(double*)*p;
time_t sec = (time_t)value;
value -= sec;
uint32_t usec = value * 1000000;
(*p)+=8;
*plist_out = plist_new_date(sec, usec);
} else if (type >= 0x08 && type <= 0x36) {
/* numerical type */
(*p)++;
uint64_t value = 0;
if (type == 0x36) {
/* double */
uint64_t u64val = float_bswap64(*(uint64_t*)(*p));
(*p)+=8;
double dval = 0;
memcpy(&dval, &u64val, 8);
*plist_out = plist_new_real(dval);
return 0;
} else if (type == 0x35) {
/* float */
uint32_t u32val = float_bswap32(*(uint32_t*)(*p));
(*p)+=4;
float fval = 0;
memcpy(&fval, &u32val, 4);
*plist_out = plist_new_real((double)fval);
return 0;
} else if (type < 0x30) {
value = type - 8;
} else if (type == 0x30) {
value = (int8_t)**p;
(*p)++;
} else if (type == 0x32) {
uint32_t u32val = *(uint32_t*)*p;
value = (int32_t)le32toh(u32val);
(p)+=4;
} else if (type == 0x33) {
uint64_t u64val = *(uint64_t*)*p;
value = le64toh(u64val);
(p)+=8;
} else {
fprintf(stderr, "%s: ERROR: Invalid encoded byte '%02x'\n", __func__, type);
*p = end;
return -1;
}
*plist_out = plist_new_uint(value);
} else if (type >= 0x40 && type <= 0x64) {
/* string */
(*p)++;
size_t slen = 0;
if (type < 0x61) {
slen = type - 0x40;
} else {
if (type == 0x61) {
slen = **p;
(*p)++;
} else if (type == 0x62) {
uint16_t u16val = *(uint16_t*)*p;
slen = le16toh(u16val);
(*p)+=2;
} else if (type == 0x63) {
uint32_t u32val = *(uint32_t*)*p;
slen = le32toh(u32val);
(*p)+=4;
} else if (type == 0x64) {
uint64_t u64val = *(uint64_t*)*p;
slen = le64toh(u64val);
(*p)+=8;
}
}
if (*p + slen > end) {
fprintf(stderr, "%s: ERROR: Size points past end of data\n", __func__);
*p = end;
return -1;
}
char* str = malloc(slen+1);
strncpy(str, (const char*)*p, slen);
str[slen] = '\0';
*plist_out = plist_new_string(str);
(*p)+=slen;
free(str);
} else if (type >= 0x70 && type <= 0x94) {
/* data */
(*p)++;
size_t dlen = 0;
if (type < 0x91) {
dlen = type - 0x70;
} else {
if (type == 0x91) {
dlen = **p;
(*p)++;
} else if (type == 0x92) {
uint16_t u16val = *(uint16_t*)*p;
dlen = le16toh(u16val);
(*p)+=2;
} else if (type == 0x93) {
uint32_t u32val = *(uint32_t*)*p;
dlen = le32toh(u32val);
(*p)+=4;
} else if (type == 0x94) {
uint64_t u64val = *(uint64_t*)*p;
dlen = le64toh(u64val);
(*p)+=8;
}
}
if (*p + dlen > end) {
fprintf(stderr, "%s: ERROR: Size points past end of data\n", __func__);
*p = end;
return -1;
}
*plist_out = plist_new_data((const char*)*p, dlen);
(*p)+=dlen;
} else if (type >= 0xE0 && type <= 0xEF) {
/* dictionary */
(*p)++;
plist_t dict = plist_new_dict();
uint32_t num_children = 0xFFFFFFFF;
if (type < 0xEF) {
/* explicit number of children */
num_children = type - 0xE0;
}
if (!*plist_out) {
*plist_out = dict;
}
uint32_t i = 0;
while (i++ < num_children) {
plist_t keynode = NULL;
int res = opack_decode_obj(p, end, &keynode, level+1);
if (res == -2) {
break;
} else if (res < 0) {
return -1;
}
if (!PLIST_IS_STRING(keynode)) {
plist_free(keynode);
fprintf(stderr, "%s: ERROR: Invalid node type for dictionary key node\n", __func__);
*p = end;
return -1;
}
char* key = NULL;
plist_get_string_val(keynode, &key);
plist_free(keynode);
plist_t valnode = NULL;
if (opack_decode_obj(p, end, &valnode, level+1) < 0) {
free(key);
return -1;
}
plist_dict_set_item(dict, key, valnode);
}
if (level == 0) {
*p = end;
return 0;
}
} else if (type >= 0xD0 && type <= 0xDF) {
/* array */
(*p)++;
plist_t array = plist_new_array();
if (!*plist_out) {
*plist_out = array;
}
uint32_t num_children = 0xFFFFFFFF;
if (type < 0xDF) {
/* explicit number of children */
num_children = type - 0xD0;
}
uint32_t i = 0;
while (i++ < num_children) {
plist_t child = NULL;
int res = opack_decode_obj(p, end, &child, level+1);
if (res == -2) {
if (type < 0xDF) {
fprintf(stderr, "%s: ERROR: Expected child node, found terminator\n", __func__);
*p = end;
return -1;
}
break;
} else if (res < 0) {
return -1;
}
plist_array_append_item(array, child);
}
if (level == 0) {
*p = end;
return 0;
}
} else {
fprintf(stderr, "%s: ERROR: Unexpected character '%02x encountered\n", __func__, type);
*p = end;
return -1;
}
return 0;
}
LIBIMOBILEDEVICE_GLUE_API int opack_decode_to_plist(unsigned char* buf, unsigned int buf_len, plist_t* plist_out)
{
if (!buf || buf_len == 0 || !plist_out) {
return -1;
}
unsigned char* p = buf;
unsigned char* end = buf + buf_len;
while (p < end) {
opack_decode_obj(&p, end, plist_out, 0);
}
return 0;
}

View File

@@ -1,319 +0,0 @@
/*
* termcolors.c
*
* Copyright (c) 2020-2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include "common.h"
#include "libimobiledevice-glue/termcolors.h"
static int use_colors = 0;
#ifdef WIN32
static int WIN32_LEGACY_MODE = 1;
static WORD COLOR_RESET_ATTR = 0;
static WORD DEFAULT_FG_ATTR = 0;
static WORD DEFAULT_BG_ATTR = 0;
static HANDLE h_stdout = INVALID_HANDLE_VALUE;
static HANDLE h_stderr = INVALID_HANDLE_VALUE;
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#define STYLE_DIM (1 << 16)
#define FG_COLOR_MASK (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
#define BG_COLOR_MASK (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
#define FG_COLOR_ATTR_MASK (FG_COLOR_MASK | FOREGROUND_INTENSITY)
#define BG_COLOR_ATTR_MASK (BG_COLOR_MASK | BACKGROUND_INTENSITY)
static int style_map[9] = {
/* RESET ALL */ 0,
/* BRIGHT */ FOREGROUND_INTENSITY,
/* DIM */ STYLE_DIM,
/* (n/a) */ 0,
/* UNDERLINED */ 0, // COMMON_LVB_UNDERSCORE ?
/* BLINK */ 0, // NOT SUPPORTED
/* (n/a) */ 0,
/* REVERSE CLR */ 0, // COMMON_LVB_REVERSE_VIDEO ?
/* HIDDEN */ 0 // NOT SUPPORTED
};
static int fgcolor_map[8] = {
/* BLACK */ 0,
/* RED */ FOREGROUND_RED,
/* GREEN */ FOREGROUND_GREEN,
/* YELLOW */ FOREGROUND_GREEN | FOREGROUND_RED,
/* BLUE */ FOREGROUND_BLUE,
/* MAGENTA */ FOREGROUND_BLUE | FOREGROUND_RED,
/* CYAN */ FOREGROUND_BLUE | FOREGROUND_GREEN,
/* WHITE */ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
};
static int bgcolor_map[8] = {
/* BLACK */ 0,
/* RED */ BACKGROUND_RED,
/* GREEN */ BACKGROUND_GREEN,
/* YELLOW */ BACKGROUND_GREEN | BACKGROUND_RED,
/* BLUE */ BACKGROUND_BLUE,
/* MAGENTA */ BACKGROUND_BLUE | BACKGROUND_RED,
/* CYAN */ BACKGROUND_BLUE | BACKGROUND_GREEN,
/* WHITE */ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
};
#else
static int WIN32_LEGACY_MODE = 0;
#endif
LIBIMOBILEDEVICE_GLUE_API void term_colors_init()
{
#ifdef WIN32
DWORD conmode = 0;
h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleMode(h_stdout, &conmode);
if (conmode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) {
WIN32_LEGACY_MODE = 0;
} else {
conmode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (SetConsoleMode(h_stdout, conmode)) {
WIN32_LEGACY_MODE = 0;
} else {
WIN32_LEGACY_MODE = 1;
}
}
if (WIN32_LEGACY_MODE) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(h_stdout, &csbi)) {
COLOR_RESET_ATTR = csbi.wAttributes;
DEFAULT_FG_ATTR = csbi.wAttributes & FG_COLOR_ATTR_MASK;
DEFAULT_BG_ATTR = csbi.wAttributes & BG_COLOR_ATTR_MASK;
}
h_stderr = GetStdHandle(STD_ERROR_HANDLE);
}
#endif
use_colors = isatty(1);
const char* color_env = getenv("COLOR");
if (color_env) {
long val = strtol(color_env, NULL, 10);
use_colors = (val != 0);
}
}
LIBIMOBILEDEVICE_GLUE_API void term_colors_set_enabled(int en)
{
use_colors = en;
}
LIBIMOBILEDEVICE_GLUE_API int cvfprintf(FILE* stream, const char* fmt, va_list vargs)
{
int res = 0;
int colorize = use_colors;
#ifdef WIN32
struct esc_item {
int pos;
WORD attr;
};
HANDLE h_stream = h_stdout;
if (WIN32_LEGACY_MODE) {
if (stream == stdout) {
h_stream = h_stdout;
} else if (stream == stderr) {
h_stream = h_stderr;
} else {
colorize = 0;
}
}
#endif
if (!colorize || WIN32_LEGACY_MODE) {
// first, we need to print the string WITH escape sequences
va_list vargs_copy;
va_copy(vargs_copy, vargs);
int len = vsnprintf(NULL, 0, fmt, vargs);
char* newbuf = (char*)malloc(len+1);
res = vsnprintf(newbuf, len+1, fmt, vargs_copy);
va_end(vargs_copy);
// then, we need to remove the escape sequences, if any
#ifdef WIN32
// if colorize is on, we need to keep their positions for later
struct esc_item* esc_items = NULL;
int attr = 0;
if (colorize) {
esc_items = (struct esc_item*)malloc(sizeof(struct esc_item) * ((len/3)+1));
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(h_stream, &csbi)) {
attr = csbi.wAttributes;
}
}
#endif
int num_esc = 0;
char* start = &newbuf[0];
char* p = start;
char* end = start + len + 1;
while (p < end-1) {
char* cur = p;
if (*p == '\e' && end-p > 2 && *(p+1) == '[') {
p+=2;
if (*p == 'm') {
#ifdef WIN32
attr = COLOR_RESET_ATTR;
#endif
int move_by = (p+1)-cur;
int move_amount = end-(p+1);
memmove(cur, p+1, move_amount);
end -= move_by;
p = cur;
} else {
char* endp = NULL;
do {
long lval = strtol(p, &endp, 10);
if (!endp || (*endp != ';' && *endp != 'm')) {
fprintf(stderr, "\n*** %s: Invalid escape sequence in format string, expected ';' or 'm' ***\n", __func__);
#ifdef WIN32
free(esc_items);
#endif
free(newbuf);
return -1;
}
#ifdef WIN32
if (colorize) {
if (lval >= 0 && lval <= 8) {
/* style attributes */
attr &= ~FOREGROUND_INTENSITY;
attr |= style_map[lval];
} else if (lval >= 30 && lval <= 37) {
/* foreground color */
attr &= ~FG_COLOR_MASK;
attr |= fgcolor_map[lval-30];
} else if (lval == 39) {
/* default foreground color */
attr &= ~FG_COLOR_ATTR_MASK;
attr |= DEFAULT_FG_ATTR;
} else if (lval >= 40 && lval <= 47) {
/* background color */
attr &= ~BG_COLOR_MASK;
attr |= bgcolor_map[lval-40];
} else if (lval == 49) {
/* default background color */
attr &= ~BG_COLOR_ATTR_MASK;
attr |= DEFAULT_BG_ATTR;
} else if (lval >= 90 && lval <= 97) {
/* foreground color bright */
attr &= ~FG_COLOR_ATTR_MASK;
attr |= fgcolor_map[lval-90];
attr |= FOREGROUND_INTENSITY;
} else if (lval >= 100 && lval <= 107) {
/* background color bright */
attr &= ~BG_COLOR_MASK;
attr |= bgcolor_map[lval-100];
attr |= BACKGROUND_INTENSITY;
}
}
#else
(void)lval; // suppress compiler warning about unused variable
#endif
p = endp+1;
} while (p < end && *endp == ';');
int move_by = (endp+1)-cur;
int move_amount = end-(endp+1);
memmove(cur, endp+1, move_amount);
end -= move_by;
p = cur;
}
#ifdef WIN32
if (colorize) {
esc_items[num_esc].pos = p-start;
if (attr & STYLE_DIM) {
attr &= ~STYLE_DIM;
attr &= ~FOREGROUND_INTENSITY;
}
esc_items[num_esc].attr = (WORD)attr;
num_esc++;
}
#endif
} else {
p++;
}
}
if (num_esc == 0) {
res = fputs(newbuf, stream);
free(newbuf);
#ifdef WIN32
free(esc_items);
#endif
return res;
}
#ifdef WIN32
else {
p = &newbuf[0];
char* lastp = &newbuf[0];
int i;
for (i = 0; i < num_esc; i++) {
p = &newbuf[esc_items[i].pos];
if (lastp < p) {
fprintf(stream, "%.*s", (int)(p-lastp), lastp);
lastp = p;
}
SetConsoleTextAttribute(h_stream, esc_items[i].attr);
}
if (lastp < end) {
fprintf(stream, "%.*s", (int)(end-lastp), lastp);
}
return res;
}
#endif
} else {
res = vfprintf(stream, fmt, vargs);
}
return res;
}
LIBIMOBILEDEVICE_GLUE_API int cfprintf(FILE* stream, const char* fmt, ...)
{
int res = 0;
va_list va;
va_start(va, fmt);
res = cvfprintf(stream, fmt, va);
va_end(va);
return res;
}
LIBIMOBILEDEVICE_GLUE_API int cprintf(const char* fmt, ...)
{
int res = 0;
va_list va;
va_start(va, fmt);
res = cvfprintf(stdout, fmt, va);
va_end(va);
return res;
}

View File

@@ -1,216 +0,0 @@
/*
* thread.c
*
* Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2012 Martin Szulecki, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "common.h"
#include "libimobiledevice-glue/thread.h"
LIBIMOBILEDEVICE_GLUE_API int thread_new(THREAD_T *thread, thread_func_t thread_func, void* data)
{
#ifdef WIN32
HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL);
if (th == NULL) {
return -1;
}
*thread = th;
return 0;
#else
int res = pthread_create(thread, NULL, thread_func, data);
return res;
#endif
}
LIBIMOBILEDEVICE_GLUE_API void thread_detach(THREAD_T thread)
{
#ifdef WIN32
CloseHandle(thread);
#else
pthread_detach(thread);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void thread_free(THREAD_T thread)
{
#ifdef WIN32
CloseHandle(thread);
#endif
}
LIBIMOBILEDEVICE_GLUE_API int thread_join(THREAD_T thread)
{
/* wait for thread to complete */
#ifdef WIN32
return (int)WaitForSingleObject(thread, INFINITE);
#else
return pthread_join(thread, NULL);
#endif
}
LIBIMOBILEDEVICE_GLUE_API int thread_alive(THREAD_T thread)
{
if (!thread)
return 0;
#ifdef WIN32
return WaitForSingleObject(thread, 0) == WAIT_TIMEOUT;
#else
return pthread_kill(thread, 0) == 0;
#endif
}
LIBIMOBILEDEVICE_GLUE_API int thread_cancel(THREAD_T thread)
{
#ifdef WIN32
return -1;
#else
#ifdef HAVE_PTHREAD_CANCEL
return pthread_cancel(thread);
#else
return -1;
#endif
#endif
}
LIBIMOBILEDEVICE_GLUE_API void mutex_init(mutex_t* mutex)
{
#ifdef WIN32
InitializeCriticalSection(mutex);
#else
pthread_mutex_init(mutex, NULL);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void mutex_destroy(mutex_t* mutex)
{
#ifdef WIN32
DeleteCriticalSection(mutex);
#else
pthread_mutex_destroy(mutex);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void mutex_lock(mutex_t* mutex)
{
#ifdef WIN32
EnterCriticalSection(mutex);
#else
pthread_mutex_lock(mutex);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void mutex_unlock(mutex_t* mutex)
{
#ifdef WIN32
LeaveCriticalSection(mutex);
#else
pthread_mutex_unlock(mutex);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void thread_once(thread_once_t *once_control, void (*init_routine)(void))
{
#ifdef WIN32
while (InterlockedExchange(&(once_control->lock), 1) != 0) {
Sleep(1);
}
if (!once_control->state) {
once_control->state = 1;
init_routine();
}
InterlockedExchange(&(once_control->lock), 0);
#else
pthread_once(once_control, init_routine);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void cond_init(cond_t* cond)
{
#ifdef WIN32
cond->sem = CreateSemaphore(NULL, 0, 32767, NULL);
#else
pthread_cond_init(cond, NULL);
#endif
}
LIBIMOBILEDEVICE_GLUE_API void cond_destroy(cond_t* cond)
{
#ifdef WIN32
CloseHandle(cond->sem);
#else
pthread_cond_destroy(cond);
#endif
}
LIBIMOBILEDEVICE_GLUE_API int cond_signal(cond_t* cond)
{
#ifdef WIN32
int result = 0;
if (!ReleaseSemaphore(cond->sem, 1, NULL)) {
result = -1;
}
return result;
#else
return pthread_cond_signal(cond);
#endif
}
LIBIMOBILEDEVICE_GLUE_API int cond_wait(cond_t* cond, mutex_t* mutex)
{
#ifdef WIN32
mutex_unlock(mutex);
DWORD res = WaitForSingleObject(cond->sem, INFINITE);
switch (res) {
case WAIT_OBJECT_0:
return 0;
default:
return -1;
}
#else
return pthread_cond_wait(cond, mutex);
#endif
}
LIBIMOBILEDEVICE_GLUE_API int cond_wait_timeout(cond_t* cond, mutex_t* mutex, unsigned int timeout_ms)
{
#ifdef WIN32
mutex_unlock(mutex);
DWORD res = WaitForSingleObject(cond->sem, timeout_ms);
switch (res) {
case WAIT_OBJECT_0:
case WAIT_TIMEOUT:
return 0;
default:
return -1;
}
#else
struct timespec ts;
struct timeval now;
gettimeofday(&now, NULL);
ts.tv_sec = now.tv_sec + timeout_ms / 1000;
ts.tv_nsec = now.tv_usec * 1000 + 1000 * 1000 * (timeout_ms % 1000);
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= (1000 * 1000 * 1000);
return pthread_cond_timedwait(cond, mutex, &ts);
#endif
}

View File

@@ -1,196 +0,0 @@
/*
* tlv.c
* Simple TLV implementation.
*
* Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
#include "libimobiledevice-glue/tlv.h"
#include "endianness.h"
LIBIMOBILEDEVICE_GLUE_API tlv_buf_t tlv_buf_new()
{
tlv_buf_t tlv = malloc(sizeof(struct tlv_buf));
tlv->capacity = 1024;
tlv->length = 0;
tlv->data = malloc(tlv->capacity);
return tlv;
}
LIBIMOBILEDEVICE_GLUE_API void tlv_buf_free(tlv_buf_t tlv)
{
if (tlv) {
free(tlv->data);
free(tlv);
}
}
LIBIMOBILEDEVICE_GLUE_API void tlv_buf_append(tlv_buf_t tlv, uint8_t tag, unsigned int length, void* data)
{
if (!tlv || !tlv->data) {
return;
}
unsigned int req_len = (length > 255) ? (length / 255) * 257 + (2 + (length % 255)) : length;
if (tlv->length + req_len > tlv->capacity) {
unsigned int newcapacity = tlv->capacity + ((req_len / 1024) + 1) * 1024;
unsigned char* newdata = realloc(tlv->data, newcapacity);
if (!newdata) {
fprintf(stderr, "%s: ERROR: Failed to realloc\n", __func__);
return;
}
tlv->data = newdata;
tlv->capacity = newcapacity;
}
unsigned char* p = tlv->data + tlv->length;
unsigned int cur = 0;
while (length - cur > 0) {
if (length - cur > 255) {
*(p++) = tag;
*(p++) = 0xFF;
memcpy(p, (unsigned char*)data + cur, 255);
p += 255;
cur += 255;
} else {
uint8_t rem = length - cur;
*(p++) = tag;
*(p++) = rem;
memcpy(p, (unsigned char*)data + cur, rem);
p += rem;
cur += rem;
}
}
tlv->length = p - tlv->data;
}
LIBIMOBILEDEVICE_GLUE_API unsigned char* tlv_get_data_ptr(const void* tlv_data, void* tlv_end, uint8_t tag, uint8_t* length)
{
unsigned char* p = (unsigned char*)tlv_data;
unsigned char* end = (unsigned char*)tlv_end;
while (p < end) {
uint8_t cur_tag = *(p++);
uint8_t len = *(p++);
if (cur_tag == tag) {
*length = len;
return p;
}
p+=len;
}
return NULL;
}
LIBIMOBILEDEVICE_GLUE_API int tlv_data_get_uint(const void* tlv_data, unsigned int tlv_length, uint8_t tag, uint64_t* value)
{
if (!tlv_data || tlv_length < 2 || !value) {
return 0;
}
uint8_t length = 0;
unsigned char* ptr = tlv_get_data_ptr(tlv_data, (unsigned char*)tlv_data+tlv_length, tag, &length);
if (!ptr) {
return 0;
}
if (ptr + length > (unsigned char*)tlv_data + tlv_length) {
return 0;
}
if (length == 1) {
uint8_t val = *ptr;
*value = val;
} else if (length == 2) {
uint16_t val = *(uint16_t*)ptr;
val = le16toh(val);
*value = val;
} else if (length == 4) {
uint32_t val = *(uint32_t*)ptr;
val = le32toh(val);
*value = val;
} else if (length == 8) {
uint64_t val = *(uint64_t*)ptr;
val = le64toh(val);
*value = val;
} else {
return 0;
}
return 1;
}
LIBIMOBILEDEVICE_GLUE_API int tlv_data_get_uint8(const void* tlv_data, unsigned int tlv_length, uint8_t tag, uint8_t* value)
{
if (!tlv_data || tlv_length < 2 || !value) {
return 0;
}
uint8_t length = 0;
unsigned char* ptr = tlv_get_data_ptr(tlv_data, (unsigned char*)tlv_data+tlv_length, tag, &length);
if (!ptr) {
return 0;
}
if (length != 1) {
return 0;
}
if (ptr + length > (unsigned char*)tlv_data + tlv_length) {
return 0;
}
*value = *ptr;
return 1;
}
LIBIMOBILEDEVICE_GLUE_API int tlv_data_copy_data(const void* tlv_data, unsigned int tlv_length, uint8_t tag, void** out, unsigned int* out_len)
{
if (!tlv_data || tlv_length < 2 || !out || !out_len) {
return 0;
}
*out = NULL;
*out_len = 0;
unsigned char* dest = NULL;
unsigned int dest_len = 0;
unsigned char* ptr = (unsigned char*)tlv_data;
unsigned char* end = (unsigned char*)tlv_data + tlv_length;
while (ptr < end) {
uint8_t length = 0;
ptr = tlv_get_data_ptr(ptr, end, tag, &length);
if (!ptr) {
break;
}
unsigned char* newdest = realloc(dest, dest_len + length);
if (!newdest) {
free(dest);
return 0;
}
dest = newdest;
memcpy(dest + dest_len, ptr, length);
dest_len += length;
ptr += length;
}
if (!dest) {
return 0;
}
*out = (void*)dest;
*out_len = dest_len;
return 1;
}

View File

@@ -1,558 +0,0 @@
/*
* utils.c
* Miscellaneous utilities for string manipulation,
* file I/O and plist helper.
*
* Copyright (c) 2014-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2013-2014 Martin Szulecki, All Rights Reserved.
* Copyright (c) 2013 Federico Mena Quintero
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <inttypes.h>
#include <ctype.h>
#include <errno.h>
#include "common.h"
#include "libimobiledevice-glue/utils.h"
#ifndef HAVE_STPCPY
#undef stpcpy
char *stpcpy(char *s1, const char *s2);
/**
* Copy characters from one string into another
*
* @note: The strings should not overlap, as the behavior is undefined.
*
* @s1: The source string.
* @s2: The destination string.
*
* @return a pointer to the terminating `\0' character of @s1,
* or NULL if @s1 or @s2 is NULL.
*/
char *stpcpy(char *s1, const char *s2)
{
if (s1 == NULL || s2 == NULL)
return NULL;
strcpy(s1, s2);
return s1 + strlen(s2);
}
#endif
/**
* Concatenate strings into a newly allocated string
*
* @note: Specify NULL for the last string in the varargs list
*
* @str: The first string in the list
* @...: Subsequent strings. Use NULL for the last item.
*
* @return a newly allocated string, or NULL if @str is NULL. This will also
* return NULL and set errno to ENOMEM if memory is exhausted.
*/
LIBIMOBILEDEVICE_GLUE_API char *string_concat(const char *str, ...)
{
size_t len;
va_list args;
char *s;
char *result;
char *dest;
if (!str)
return NULL;
/* Compute final length */
len = strlen(str) + 1; /* plus 1 for the null terminator */
va_start(args, str);
s = va_arg(args, char *);
while (s) {
len += strlen(s);
s = va_arg(args, char*);
}
va_end(args);
/* Concat each string */
result = malloc(len);
if (!result)
return NULL; /* errno remains set */
dest = result;
dest = stpcpy(dest, str);
va_start(args, str);
s = va_arg(args, char *);
while (s) {
dest = stpcpy(dest, s);
s = va_arg(args, char *);
}
va_end(args);
return result;
}
LIBIMOBILEDEVICE_GLUE_API char *string_append(char* str, ...)
{
size_t len = 0;
size_t slen;
va_list args;
char *s;
char *result;
char *dest;
/* Compute final length */
if (str) {
len = strlen(str);
}
slen = len;
len++; /* plus 1 for the null terminator */
va_start(args, str);
s = va_arg(args, char *);
while (s) {
len += strlen(s);
s = va_arg(args, char*);
}
va_end(args);
result = realloc(str, len);
if (!result)
return NULL; /* errno remains set */
dest = result + slen;
/* Concat additional strings */
va_start(args, str);
s = va_arg(args, char *);
while (s) {
dest = stpcpy(dest, s);
s = va_arg(args, char *);
}
va_end(args);
return result;
}
LIBIMOBILEDEVICE_GLUE_API char *string_build_path(const char *elem, ...)
{
if (!elem)
return NULL;
va_list args;
int len = strlen(elem)+1;
va_start(args, elem);
char *arg = va_arg(args, char*);
while (arg) {
len += strlen(arg)+1;
arg = va_arg(args, char*);
}
va_end(args);
char* out = (char*)malloc(len);
strcpy(out, elem);
va_start(args, elem);
arg = va_arg(args, char*);
while (arg) {
strcat(out, "/");
strcat(out, arg);
arg = va_arg(args, char*);
}
va_end(args);
return out;
}
LIBIMOBILEDEVICE_GLUE_API char *string_format_size(uint64_t size)
{
char buf[80];
double sz;
if (size >= 1000000000000LL) {
sz = ((double)size / 1000000000000.0F);
sprintf(buf, "%0.1f TB", sz);
} else if (size >= 1000000000LL) {
sz = ((double)size / 1000000000.0F);
sprintf(buf, "%0.1f GB", sz);
} else if (size >= 1000000LL) {
sz = ((double)size / 1000000.0F);
sprintf(buf, "%0.1f MB", sz);
} else if (size >= 1000LL) {
sz = ((double)size / 1000.0F);
sprintf(buf, "%0.1f KB", sz);
} else {
sprintf(buf, "%d Bytes", (int)size);
}
return strdup(buf);
}
LIBIMOBILEDEVICE_GLUE_API char *string_toupper(char* str)
{
char *res = strdup(str);
size_t i;
for (i = 0; i < strlen(res); i++) {
res[i] = toupper(res[i]);
}
return res;
}
static int get_rand(int min, int max)
{
int retval = (rand() % (max - min)) + min;
return retval;
}
LIBIMOBILEDEVICE_GLUE_API char *generate_uuid()
{
const char *chars = "ABCDEF0123456789";
int i = 0;
char *uuid = (char *) malloc(sizeof(char) * 37);
srand(time(NULL));
for (i = 0; i < 36; i++) {
if (i == 8 || i == 13 || i == 18 || i == 23) {
uuid[i] = '-';
continue;
}
uuid[i] = chars[get_rand(0, 16)];
}
/* make it a real string */
uuid[36] = '\0';
return uuid;
}
LIBIMOBILEDEVICE_GLUE_API int buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length)
{
FILE *f;
uint64_t size;
if (!filename || !buffer || !length) {
return 0;
}
*length = 0;
f = fopen(filename, "rb");
if (!f) {
return 0;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
rewind(f);
if (size == 0) {
fclose(f);
return 0;
}
*buffer = (char*)malloc(sizeof(char)*(size+1));
if (*buffer == NULL) {
fclose(f);
return 0;
}
int ret = 1;
if (fread(*buffer, sizeof(char), size, f) != size) {
free(*buffer);
ret = 0;
errno = EIO;
}
fclose(f);
*length = size;
return ret;
}
LIBIMOBILEDEVICE_GLUE_API int buffer_write_to_filename(const char *filename, const char *buffer, uint64_t length)
{
FILE *f;
f = fopen(filename, "wb");
if (f) {
size_t written = fwrite(buffer, sizeof(char), length, f);
fclose(f);
if (written == length) {
return 1;
}
else {
// Not all data could be written.
errno = EIO;
return 0;
}
}
else {
// Failed to open the file, let the caller know.
return 0;
}
}
LIBIMOBILEDEVICE_GLUE_API int plist_read_from_filename(plist_t *plist, const char *filename)
{
char *buffer = NULL;
uint64_t length;
if (!filename)
return 0;
if (!buffer_read_from_filename(filename, &buffer, &length)) {
return 0;
}
plist_from_memory(buffer, length, plist);
free(buffer);
return 1;
}
LIBIMOBILEDEVICE_GLUE_API int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format)
{
char *buffer = NULL;
uint32_t length;
if (!plist || !filename)
return 0;
if (format == PLIST_FORMAT_XML)
plist_to_xml(plist, &buffer, &length);
else if (format == PLIST_FORMAT_BINARY)
plist_to_bin(plist, &buffer, &length);
else
return 0;
int res = buffer_write_to_filename(filename, buffer, length);
free(buffer);
return res;
}
static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64_pad = '=';
static char *base64encode(const unsigned char *buf, size_t size)
{
if (!buf || !(size > 0)) return NULL;
int outlen = (size / 3) * 4;
char *outbuf = (char*)malloc(outlen+5); // 4 spare bytes + 1 for '\0'
size_t n = 0;
size_t m = 0;
unsigned char input[3];
unsigned int output[4];
while (n < size) {
input[0] = buf[n];
input[1] = (n+1 < size) ? buf[n+1] : 0;
input[2] = (n+2 < size) ? buf[n+2] : 0;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 3) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 15) << 2) + (input[2] >> 6);
output[3] = input[2] & 63;
outbuf[m++] = base64_str[(int)output[0]];
outbuf[m++] = base64_str[(int)output[1]];
outbuf[m++] = (n+1 < size) ? base64_str[(int)output[2]] : base64_pad;
outbuf[m++] = (n+2 < size) ? base64_str[(int)output[3]] : base64_pad;
n+=3;
}
outbuf[m] = 0; // 0-termination!
return outbuf;
}
static void plist_node_print_to_stream(plist_t node, int* indent_level, FILE* stream);
static void plist_array_print_to_stream(plist_t node, int* indent_level, FILE* stream)
{
/* iterate over items */
int i, count;
plist_t subnode = NULL;
count = plist_array_get_size(node);
for (i = 0; i < count; i++) {
subnode = plist_array_get_item(node, i);
fprintf(stream, "%*s", *indent_level, "");
fprintf(stream, "%d: ", i);
plist_node_print_to_stream(subnode, indent_level, stream);
}
}
static void plist_dict_print_to_stream(plist_t node, int* indent_level, FILE* stream)
{
/* iterate over key/value pairs */
plist_dict_iter it = NULL;
char* key = NULL;
plist_t subnode = NULL;
plist_dict_new_iter(node, &it);
plist_dict_next_item(node, it, &key, &subnode);
while (subnode)
{
fprintf(stream, "%*s", *indent_level, "");
fprintf(stream, "%s", key);
if (plist_get_node_type(subnode) == PLIST_ARRAY)
fprintf(stream, "[%d]: ", plist_array_get_size(subnode));
else
fprintf(stream, ": ");
free(key);
key = NULL;
plist_node_print_to_stream(subnode, indent_level, stream);
plist_dict_next_item(node, it, &key, &subnode);
}
free(it);
}
static void plist_node_print_to_stream(plist_t node, int* indent_level, FILE* stream)
{
char *s = NULL;
char *data = NULL;
double d;
uint8_t b;
uint64_t u = 0;
struct timeval tv = { 0, 0 };
plist_type t;
if (!node)
return;
t = plist_get_node_type(node);
switch (t) {
case PLIST_BOOLEAN:
plist_get_bool_val(node, &b);
fprintf(stream, "%s\n", (b ? "true" : "false"));
break;
case PLIST_UINT:
plist_get_uint_val(node, &u);
fprintf(stream, "%"PRIu64"\n", u);
break;
case PLIST_REAL:
plist_get_real_val(node, &d);
fprintf(stream, "%f\n", d);
break;
case PLIST_STRING:
plist_get_string_val(node, &s);
fprintf(stream, "%s\n", s);
free(s);
break;
case PLIST_KEY:
plist_get_key_val(node, &s);
fprintf(stream, "%s: ", s);
free(s);
break;
case PLIST_DATA:
plist_get_data_val(node, &data, &u);
if (u > 0) {
s = base64encode((unsigned char*)data, u);
free(data);
if (s) {
fprintf(stream, "%s\n", s);
free(s);
} else {
fprintf(stream, "\n");
}
} else {
fprintf(stream, "\n");
}
break;
case PLIST_DATE:
plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
{
time_t ti = (time_t)tv.tv_sec + MAC_EPOCH;
struct tm *btime = localtime(&ti);
if (btime) {
s = (char*)malloc(24);
memset(s, 0, 24);
if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
free (s);
s = NULL;
}
}
}
if (s) {
fprintf(stream, "%s\n", s);
free(s);
} else {
fprintf(stream, "\n");
}
break;
case PLIST_ARRAY:
fprintf(stream, "\n");
(*indent_level)++;
plist_array_print_to_stream(node, indent_level, stream);
(*indent_level)--;
break;
case PLIST_DICT:
fprintf(stream, "\n");
(*indent_level)++;
plist_dict_print_to_stream(node, indent_level, stream);
(*indent_level)--;
break;
default:
break;
}
}
LIBIMOBILEDEVICE_GLUE_API void plist_print_to_stream_with_indentation(plist_t plist, FILE* stream, unsigned int indentation)
{
if (!plist || !stream)
return;
int indent = indentation;
switch (plist_get_node_type(plist)) {
case PLIST_DICT:
plist_dict_print_to_stream(plist, &indent, stream);
break;
case PLIST_ARRAY:
plist_array_print_to_stream(plist, &indent, stream);
break;
default:
plist_node_print_to_stream(plist, &indent, stream);
}
}
LIBIMOBILEDEVICE_GLUE_API void plist_print_to_stream(plist_t plist, FILE* stream)
{
plist_print_to_stream_with_indentation(plist, stream, 0);
}

View File

@@ -1 +0,0 @@
* text=auto

View File

@@ -1,229 +0,0 @@
name: build
on:
push:
schedule:
- cron: '0 0 1 * *'
jobs:
build-linux-ubuntu:
runs-on: ubuntu-latest
steps:
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install cython3
- name: prepare environment
run: |
echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_${{env.target_triplet}}
repo: libimobiledevice/libplist
- name: fetch libusbmuxd
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libusbmuxd-latest_${{env.target_triplet}}
repo: libimobiledevice/libusbmuxd
- name: fetch libimobiledevice-glue
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libimobiledevice-glue-latest_${{env.target_triplet}}
repo: libimobiledevice/libimobiledevice-glue
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
sudo cp -r extract/* /
sudo ldconfig
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: autogen
run: ./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig LDFLAGS="-Wl,-rpath=/usr/local/lib" --enable-debug
- name: make
run: make
- name: make install
run: sudo make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar usr
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-latest_${{env.target_triplet}}
path: libimobiledevice.tar
build-macOS:
runs-on: macOS-latest
steps:
- name: install dependencies
run: |
if test -x "`which port`"; then
sudo port install libtool autoconf automake pkgconfig
else
brew install libtool autoconf automake pkgconfig
fi
pip install cython
shell: bash
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_macOS
repo: libimobiledevice/libplist
- name: fetch libusbmuxd
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libusbmuxd-latest_macOS
repo: libimobiledevice/libusbmuxd
- name: fetch libimobiledevice-glue
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libimobiledevice-glue-latest_macOS
repo: libimobiledevice/libimobiledevice-glue
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
sudo cp -r extract/* /
- uses: actions/checkout@v2
- name: install additional requirements
run: |
mkdir -p lib
curl -o lib/libcrypto.35.tbd -Ls \
https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libcrypto.35.tbd
curl -o lib/libssl.35.tbd -Ls \
https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libssl.35.tbd
echo "LIBSSL=`pwd`/lib/libssl.35.tbd" >> $GITHUB_ENV
echo "LIBCRYPTO=`pwd`/lib/libcrypto.35.tbd" >> $GITHUB_ENV
LIBRESSL_VER=2.2.7
echo "LIBRESSL_VER=$LIBRESSL_VER" >> $GITHUB_ENV
FILENAME="libressl-$LIBRESSL_VER.tar.gz"
curl -o $FILENAME -Ls "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$FILENAME"
mkdir -p deps
tar -C deps -xzf $FILENAME
echo "DEPSDIR=`pwd`/deps" >> $GITHUB_ENV
- name: autogen
run: |
SDKDIR=`xcrun --sdk macosx --show-sdk-path`
TESTARCHS="arm64 x86_64"
USEARCHS=
for ARCH in $TESTARCHS; do
if echo "int main(int argc, char **argv) { return 0; }" |clang -arch $ARCH -o /dev/null -isysroot $SDKDIR -x c - 2>/dev/null; then
USEARCHS="$USEARCHS -arch $ARCH"
fi
done
export CFLAGS="$USEARCHS -isysroot $SDKDIR"
echo "Using CFLAGS: $CFLAGS"
./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig --enable-debug \
openssl_CFLAGS="-I${{ env.DEPSDIR }}/libressl-${{ env.LIBRESSL_VER }}/include" \
openssl_LIBS="-Xlinker ${{ env.LIBSSL }} -Xlinker ${{ env.LIBCRYPTO }}"
- name: make
run: make
- name: make install
run: sudo make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar usr
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-latest_macOS
path: libimobiledevice.tar
build-windows:
runs-on: windows-2019
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
include: [
{ msystem: MINGW64, arch: x86_64 },
{ msystem: MINGW32, arch: i686 }
]
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
release: false
update: false
install: >-
base-devel
git
mingw-w64-${{ matrix.arch }}-gcc
make
libtool
autoconf
automake-wrapper
- name: prepare environment
run: |
dest=`echo ${{ matrix.msystem }} |tr [:upper:] [:lower:]`
echo "dest=$dest" >> $GITHUB_ENV
echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
git config --global core.autocrlf false
- name: fetch libplist
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libplist-latest_${{ matrix.arch }}-${{ env.dest }}
repo: libimobiledevice/libplist
- name: fetch libusbmuxd
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libusbmuxd-latest_${{ matrix.arch }}-${{ env.dest }}
repo: libimobiledevice/libusbmuxd
- name: fetch libimobiledevice-glue
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{secrets.GITHUB_TOKEN}}
workflow: build.yml
name: libimobiledevice-glue-latest_${{ matrix.arch }}-${{ env.dest }}
repo: libimobiledevice/libimobiledevice-glue
- name: install external dependencies
run: |
mkdir extract
for I in *.tar; do
tar -C extract -xvf $I
done
cp -r extract/* /
- uses: actions/checkout@v2
- name: autogen
run: ./autogen.sh CC=gcc CXX=g++ --enable-debug
- name: make
run: make
- name: make install
run: make install
- name: prepare artifact
run: |
mkdir -p dest
DESTDIR=`pwd`/dest make install
tar -C dest -cf libimobiledevice.tar ${{ env.dest }}
- name: publish artifact
uses: actions/upload-artifact@v2
with:
name: libimobiledevice-latest_${{ matrix.arch }}-${{ env.dest }}
path: libimobiledevice.tar

View File

@@ -1,43 +0,0 @@
# git-ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
*.[oa]
*~
*.po
*.lo
*.la
autom4te.cache/*
*.in
*/.deps/*
m4/*
swig/*
*.swp
*.patch
aclocal.m4
config.h
config.log
config.sub
config.guess
config.status
configure
depcomp
install-sh
compile
main
ltmain.sh
missing
mkinstalldirs
libtool
*Makefile
py-compile
stamp-h1
src/.libs
docs/html
libimobiledevice-1.0.pc
tools/.libs/*
tools/idevice*
!tools/idevice*.[ch]
cython/.libs/*
cython/*.c
doxygen.cfg

View File

@@ -1,6 +0,0 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
SUBDIRS =
if HAVE_WIRELESS_PAIRING
SUBDIRS += ed25519 libsrp6a-sha512
endif

View File

@@ -1,36 +0,0 @@
# Third party components/libraries
This folder contains third party components or libraries that are used
within the libimobiledevice project. They have been bundled since they
are either not readily available on the intended target platforms and/or
have been modified.
Their respective licenses are provided in each corresponding folder in a
file called LICENSE.
## ed25519
Source: https://github.com/orlp/ed25519
Based on commit 7fa6712ef5d581a6981ec2b08ee623314cd1d1c4.
[LICENCE](ed25519/LICENSE)
The original source has not been modified, except that the file `test.c`
and the contained DLL files have been removed. To allow building within
libimobiledevice, a `Makefile.am` has been added.
## libsrp6a-sha512
Source: https://github.com/secure-remote-password/stanford-srp
Based on commit 587900d32777348f98477cb25123d5761fbe3725.
[LICENCE](libsrp6a-sha512/LICENSE)
For the usage within libimobiledevice, only [libsrp](https://github.com/secure-remote-password/stanford-srp/tree/master/libsrp)
has been used as a basis.
It has been adapted to the needs of the libimobiledevice project, and
contains just a part of the original code; it only supports the SRP6a
client method which has been modified to use SHA512 instead of SHA1,
hence the name was changed to `libsrp6a-sha512`.
More details about the modifications can be found in [libsrp6a-sha512/README.md](libsrp6a-sha512/README.md).

View File

@@ -1,16 +0,0 @@
Copyright (c) 2015 Orson Peters <orsonpeters@gmail.com>
This software is provided 'as-is', without any express or implied warranty. In no event will the
authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the
original software. If you use this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as
being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@@ -1,26 +0,0 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
$(openssl_CFLAGS)
AM_LDFLAGS =
noinst_LTLIBRARIES = libed25519.la
libed25519_la_LIBADD =
libed25519_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined
libed25519_la_SOURCES = \
add_scalar.c \
fe.c \
ge.c \
keypair.c \
key_exchange.c \
sc.c \
seed.c \
sign.c \
sha512.c \
verify.c

View File

@@ -1,165 +0,0 @@
Ed25519
=======
This is a portable implementation of [Ed25519](http://ed25519.cr.yp.to/) based
on the SUPERCOP "ref10" implementation. Additionally there is key exchanging
and scalar addition included to further aid building a PKI using Ed25519. All
code is licensed under the permissive zlib license.
All code is pure ANSI C without any dependencies, except for the random seed
generation which uses standard OS cryptography APIs (`CryptGenRandom` on
Windows, `/dev/urandom` on nix). If you wish to be entirely portable define
`ED25519_NO_SEED`. This disables the `ed25519_create_seed` function, so if your
application requires key generation you must supply your own seeding function
(which is simply a 256 bit (32 byte) cryptographic random number generator).
Performance
-----------
On a Windows machine with an Intel Pentium B970 @ 2.3GHz I got the following
speeds (running on only one a single core):
Seed generation: 64us (15625 per second)
Key generation: 88us (11364 per second)
Message signing (short message): 87us (11494 per second)
Message verifying (short message): 228us (4386 per second)
Scalar addition: 100us (10000 per second)
Key exchange: 220us (4545 per second)
The speeds on other machines may vary. Sign/verify times will be higher with
longer messages. The implementation significantly benefits from 64 bit
architectures, if possible compile as 64 bit.
Usage
-----
Simply add all .c and .h files in the `src/` folder to your project and include
`ed25519.h` in any file you want to use the API. If you prefer to use a shared
library, only copy `ed25519.h` and define `ED25519_DLL` before importing.
There are no defined types for seeds, private keys, public keys, shared secrets
or signatures. Instead simple `unsigned char` buffers are used with the
following sizes:
```c
unsigned char seed[32];
unsigned char signature[64];
unsigned char public_key[32];
unsigned char private_key[64];
unsigned char scalar[32];
unsigned char shared_secret[32];
```
API
---
```c
int ed25519_create_seed(unsigned char *seed);
```
Creates a 32 byte random seed in `seed` for key generation. `seed` must be a
writable 32 byte buffer. Returns 0 on success, and nonzero on failure.
```c
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key,
const unsigned char *seed);
```
Creates a new key pair from the given seed. `public_key` must be a writable 32
byte buffer, `private_key` must be a writable 64 byte buffer and `seed` must be
a 32 byte buffer.
```c
void ed25519_sign(unsigned char *signature,
const unsigned char *message, size_t message_len,
const unsigned char *public_key, const unsigned char *private_key);
```
Creates a signature of the given message with the given key pair. `signature`
must be a writable 64 byte buffer. `message` must have at least `message_len`
bytes to be read.
```c
int ed25519_verify(const unsigned char *signature,
const unsigned char *message, size_t message_len,
const unsigned char *public_key);
```
Verifies the signature on the given message using `public_key`. `signature`
must be a readable 64 byte buffer. `message` must have at least `message_len`
bytes to be read. Returns 1 if the signature matches, 0 otherwise.
```c
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key,
const unsigned char *scalar);
```
Adds `scalar` to the given key pair where scalar is a 32 byte buffer (possibly
generated with `ed25519_create_seed`), generating a new key pair. You can
calculate the public key sum without knowing the private key and vice versa by
passing in `NULL` for the key you don't know. This is useful for enforcing
randomness on a key pair by a third party while only knowing the public key,
among other things. Warning: the last bit of the scalar is ignored - if
comparing scalars make sure to clear it with `scalar[31] &= 127`.
```c
void ed25519_key_exchange(unsigned char *shared_secret,
const unsigned char *public_key, const unsigned char *private_key);
```
Performs a key exchange on the given public key and private key, producing a
shared secret. It is recommended to hash the shared secret before using it.
`shared_secret` must be a 32 byte writable buffer where the shared secret will
be stored.
Example
-------
```c
unsigned char seed[32], public_key[32], private_key[64], signature[64];
unsigned char other_public_key[32], other_private_key[64], shared_secret[32];
const unsigned char message[] = "TEST MESSAGE";
/* create a random seed, and a key pair out of that seed */
if (ed25519_create_seed(seed)) {
printf("error while generating seed\n");
exit(1);
}
ed25519_create_keypair(public_key, private_key, seed);
/* create signature on the message with the key pair */
ed25519_sign(signature, message, strlen(message), public_key, private_key);
/* verify the signature */
if (ed25519_verify(signature, message, strlen(message), public_key)) {
printf("valid signature\n");
} else {
printf("invalid signature\n");
}
/* create a dummy keypair to use for a key exchange, normally you'd only have
the public key and receive it through some communication channel */
if (ed25519_create_seed(seed)) {
printf("error while generating seed\n");
exit(1);
}
ed25519_create_keypair(other_public_key, other_private_key, seed);
/* do a key exchange with other_public_key */
ed25519_key_exchange(shared_secret, other_public_key, private_key);
/*
the magic here is that ed25519_key_exchange(shared_secret, public_key,
other_private_key); would result in the same shared_secret
*/
```
License
-------
All code is released under the zlib license. See LICENSE for details.

View File

@@ -1,69 +0,0 @@
#include "ed25519.h"
#include "ge.h"
#include "sc.h"
#include "sha512.h"
/* see http://crypto.stackexchange.com/a/6215/4697 */
void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) {
const unsigned char SC_1[32] = {1}; /* scalar with value 1 */
unsigned char n[32];
ge_p3 nB;
ge_p1p1 A_p1p1;
ge_p3 A;
ge_p3 public_key_unpacked;
ge_cached T;
sha512_context hash;
unsigned char hashbuf[64];
int i;
/* copy the scalar and clear highest bit */
for (i = 0; i < 31; ++i) {
n[i] = scalar[i];
}
n[31] = scalar[31] & 127;
/* private key: a = n + t */
if (private_key) {
sc_muladd(private_key, SC_1, n, private_key);
// https://github.com/orlp/ed25519/issues/3
sha512_init(&hash);
sha512_update(&hash, private_key + 32, 32);
sha512_update(&hash, scalar, 32);
sha512_final(&hash, hashbuf);
for (i = 0; i < 32; ++i) {
private_key[32 + i] = hashbuf[i];
}
}
/* public key: A = nB + T */
if (public_key) {
/* if we know the private key we don't need a point addition, which is faster */
/* using a "timing attack" you could find out wether or not we know the private
key, but this information seems rather useless - if this is important pass
public_key and private_key seperately in 2 function calls */
if (private_key) {
ge_scalarmult_base(&A, private_key);
} else {
/* unpack public key into T */
ge_frombytes_negate_vartime(&public_key_unpacked, public_key);
fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */
fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */
ge_p3_to_cached(&T, &public_key_unpacked);
/* calculate n*B */
ge_scalarmult_base(&nB, n);
/* A = n*B + T */
ge_add(&A_p1p1, &nB, &T);
ge_p1p1_to_p3(&A, &A_p1p1);
}
/* pack public key */
ge_p3_tobytes(public_key, &A);
}
}

View File

@@ -1,38 +0,0 @@
#ifndef ED25519_H
#define ED25519_H
#include <stddef.h>
#if defined(_WIN32)
#if defined(ED25519_BUILD_DLL)
#define ED25519_DECLSPEC __declspec(dllexport)
#elif defined(ED25519_DLL)
#define ED25519_DECLSPEC __declspec(dllimport)
#else
#define ED25519_DECLSPEC
#endif
#else
#define ED25519_DECLSPEC
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ED25519_NO_SEED
int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed);
#endif
void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key);
int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key);
void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,41 +0,0 @@
#ifndef FE_H
#define FE_H
#include "fixedint.h"
/*
fe means field element.
Here the field is \Z/(2^255-19).
An element t, entries t[0]...t[9], represents the integer
t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
Bounds on each t[i] vary depending on context.
*/
typedef int32_t fe[10];
void fe_0(fe h);
void fe_1(fe h);
void fe_frombytes(fe h, const unsigned char *s);
void fe_tobytes(unsigned char *s, const fe h);
void fe_copy(fe h, const fe f);
int fe_isnegative(const fe f);
int fe_isnonzero(const fe f);
void fe_cmov(fe f, const fe g, unsigned int b);
void fe_cswap(fe f, fe g, unsigned int b);
void fe_neg(fe h, const fe f);
void fe_add(fe h, const fe f, const fe g);
void fe_invert(fe out, const fe z);
void fe_sq(fe h, const fe f);
void fe_sq2(fe h, const fe f);
void fe_mul(fe h, const fe f, const fe g);
void fe_mul121666(fe h, fe f);
void fe_pow22523(fe out, const fe z);
void fe_sub(fe h, const fe f, const fe g);
#endif

View File

@@ -1,72 +0,0 @@
/*
Portable header to provide the 32 and 64 bits type.
Not a compatible replacement for <stdint.h>, do not blindly use it as such.
*/
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
#include <stdint.h>
#define FIXEDINT_H_INCLUDED
#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
#include <limits.h>
#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
#endif
#endif
#ifndef FIXEDINT_H_INCLUDED
#define FIXEDINT_H_INCLUDED
#include <limits.h>
/* (u)int32_t */
#ifndef uint32_t
#if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long uint32_t;
#elif (UINT_MAX == 0xffffffffUL)
typedef unsigned int uint32_t;
#elif (USHRT_MAX == 0xffffffffUL)
typedef unsigned short uint32_t;
#endif
#endif
#ifndef int32_t
#if (LONG_MAX == 0x7fffffffL)
typedef signed long int32_t;
#elif (INT_MAX == 0x7fffffffL)
typedef signed int int32_t;
#elif (SHRT_MAX == 0x7fffffffL)
typedef signed short int32_t;
#endif
#endif
/* (u)int64_t */
#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL
#elif defined(__GNUC__)
__extension__ typedef long long int64_t;
__extension__ typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL
#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL
#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#define UINT64_C(v) v ##UI64
#define INT64_C(v) v ##I64
#endif
#endif

View File

@@ -1,467 +0,0 @@
#include "ge.h"
#include "precomp_data.h"
/*
r = p + q
*/
void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->YplusX);
fe_mul(r->Y, r->Y, q->YminusX);
fe_mul(r->T, q->T2d, p->T);
fe_mul(r->X, p->Z, q->Z);
fe_add(t0, r->X, r->X);
fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y);
fe_add(r->Z, t0, r->T);
fe_sub(r->T, t0, r->T);
}
static void slide(signed char *r, const unsigned char *a) {
int i;
int b;
int k;
for (i = 0; i < 256; ++i) {
r[i] = 1 & (a[i >> 3] >> (i & 7));
}
for (i = 0; i < 256; ++i)
if (r[i]) {
for (b = 1; b <= 6 && i + b < 256; ++b) {
if (r[i + b]) {
if (r[i] + (r[i + b] << b) <= 15) {
r[i] += r[i + b] << b;
r[i + b] = 0;
} else if (r[i] - (r[i + b] << b) >= -15) {
r[i] -= r[i + b] << b;
for (k = i + b; k < 256; ++k) {
if (!r[k]) {
r[k] = 1;
break;
}
r[k] = 0;
}
} else {
break;
}
}
}
}
}
/*
r = a * A + b * B
where a = a[0]+256*a[1]+...+256^31 a[31].
and b = b[0]+256*b[1]+...+256^31 b[31].
B is the Ed25519 base point (x,4/5) with x positive.
*/
void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
signed char aslide[256];
signed char bslide[256];
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
ge_p1p1 t;
ge_p3 u;
ge_p3 A2;
int i;
slide(aslide, a);
slide(bslide, b);
ge_p3_to_cached(&Ai[0], A);
ge_p3_dbl(&t, A);
ge_p1p1_to_p3(&A2, &t);
ge_add(&t, &A2, &Ai[0]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[1], &u);
ge_add(&t, &A2, &Ai[1]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[2], &u);
ge_add(&t, &A2, &Ai[2]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[3], &u);
ge_add(&t, &A2, &Ai[3]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[4], &u);
ge_add(&t, &A2, &Ai[4]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[5], &u);
ge_add(&t, &A2, &Ai[5]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[6], &u);
ge_add(&t, &A2, &Ai[6]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[7], &u);
ge_p2_0(r);
for (i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) {
break;
}
}
for (; i >= 0; --i) {
ge_p2_dbl(&t, r);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i] / 2]);
} else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
}
if (bslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
} else if (bslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
}
ge_p1p1_to_p2(r, &t);
}
}
static const fe d = {
-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
};
static const fe sqrtm1 = {
-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
};
int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) {
fe u;
fe v;
fe v3;
fe vxx;
fe check;
fe_frombytes(h->Y, s);
fe_1(h->Z);
fe_sq(u, h->Y);
fe_mul(v, u, d);
fe_sub(u, u, h->Z); /* u = y^2-1 */
fe_add(v, v, h->Z); /* v = dy^2+1 */
fe_sq(v3, v);
fe_mul(v3, v3, v); /* v3 = v^3 */
fe_sq(h->X, v3);
fe_mul(h->X, h->X, v);
fe_mul(h->X, h->X, u); /* x = uv^7 */
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
fe_mul(h->X, h->X, v3);
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
fe_sq(vxx, h->X);
fe_mul(vxx, vxx, v);
fe_sub(check, vxx, u); /* vx^2-u */
if (fe_isnonzero(check)) {
fe_add(check, vxx, u); /* vx^2+u */
if (fe_isnonzero(check)) {
return -1;
}
fe_mul(h->X, h->X, sqrtm1);
}
if (fe_isnegative(h->X) == (s[31] >> 7)) {
fe_neg(h->X, h->X);
}
fe_mul(h->T, h->X, h->Y);
return 0;
}
/*
r = p + q
*/
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->yplusx);
fe_mul(r->Y, r->Y, q->yminusx);
fe_mul(r->T, q->xy2d, p->T);
fe_add(t0, p->Z, p->Z);
fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y);
fe_add(r->Z, t0, r->T);
fe_sub(r->T, t0, r->T);
}
/*
r = p - q
*/
void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->yminusx);
fe_mul(r->Y, r->Y, q->yplusx);
fe_mul(r->T, q->xy2d, p->T);
fe_add(t0, p->Z, p->Z);
fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y);
fe_sub(r->Z, t0, r->T);
fe_add(r->T, t0, r->T);
}
/*
r = p
*/
void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
fe_mul(r->X, p->X, p->T);
fe_mul(r->Y, p->Y, p->Z);
fe_mul(r->Z, p->Z, p->T);
}
/*
r = p
*/
void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
fe_mul(r->X, p->X, p->T);
fe_mul(r->Y, p->Y, p->Z);
fe_mul(r->Z, p->Z, p->T);
fe_mul(r->T, p->X, p->Y);
}
void ge_p2_0(ge_p2 *h) {
fe_0(h->X);
fe_1(h->Y);
fe_1(h->Z);
}
/*
r = 2 * p
*/
void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
fe t0;
fe_sq(r->X, p->X);
fe_sq(r->Z, p->Y);
fe_sq2(r->T, p->Z);
fe_add(r->Y, p->X, p->Y);
fe_sq(t0, r->Y);
fe_add(r->Y, r->Z, r->X);
fe_sub(r->Z, r->Z, r->X);
fe_sub(r->X, t0, r->Y);
fe_sub(r->T, r->T, r->Z);
}
void ge_p3_0(ge_p3 *h) {
fe_0(h->X);
fe_1(h->Y);
fe_1(h->Z);
fe_0(h->T);
}
/*
r = 2 * p
*/
void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
ge_p2 q;
ge_p3_to_p2(&q, p);
ge_p2_dbl(r, &q);
}
/*
r = p
*/
static const fe d2 = {
-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
};
void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
fe_add(r->YplusX, p->Y, p->X);
fe_sub(r->YminusX, p->Y, p->X);
fe_copy(r->Z, p->Z);
fe_mul(r->T2d, p->T, d2);
}
/*
r = p
*/
void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
fe_copy(r->X, p->X);
fe_copy(r->Y, p->Y);
fe_copy(r->Z, p->Z);
}
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
fe recip;
fe x;
fe y;
fe_invert(recip, h->Z);
fe_mul(x, h->X, recip);
fe_mul(y, h->Y, recip);
fe_tobytes(s, y);
s[31] ^= fe_isnegative(x) << 7;
}
static unsigned char equal(signed char b, signed char c) {
unsigned char ub = b;
unsigned char uc = c;
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
uint64_t y = x; /* 0: yes; 1..255: no */
y -= 1; /* large: yes; 0..254: no */
y >>= 63; /* 1: yes; 0: no */
return (unsigned char) y;
}
static unsigned char negative(signed char b) {
uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */
return (unsigned char) x;
}
static void cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) {
fe_cmov(t->yplusx, u->yplusx, b);
fe_cmov(t->yminusx, u->yminusx, b);
fe_cmov(t->xy2d, u->xy2d, b);
}
static void select(ge_precomp *t, int pos, signed char b) {
ge_precomp minust;
unsigned char bnegative = negative(b);
unsigned char babs = b - (((-bnegative) & b) << 1);
fe_1(t->yplusx);
fe_1(t->yminusx);
fe_0(t->xy2d);
cmov(t, &base[pos][0], equal(babs, 1));
cmov(t, &base[pos][1], equal(babs, 2));
cmov(t, &base[pos][2], equal(babs, 3));
cmov(t, &base[pos][3], equal(babs, 4));
cmov(t, &base[pos][4], equal(babs, 5));
cmov(t, &base[pos][5], equal(babs, 6));
cmov(t, &base[pos][6], equal(babs, 7));
cmov(t, &base[pos][7], equal(babs, 8));
fe_copy(minust.yplusx, t->yminusx);
fe_copy(minust.yminusx, t->yplusx);
fe_neg(minust.xy2d, t->xy2d);
cmov(t, &minust, bnegative);
}
/*
h = a * B
where a = a[0]+256*a[1]+...+256^31 a[31]
B is the Ed25519 base point (x,4/5) with x positive.
Preconditions:
a[31] <= 127
*/
void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
signed char e[64];
signed char carry;
ge_p1p1 r;
ge_p2 s;
ge_precomp t;
int i;
for (i = 0; i < 32; ++i) {
e[2 * i + 0] = (a[i] >> 0) & 15;
e[2 * i + 1] = (a[i] >> 4) & 15;
}
/* each e[i] is between 0 and 15 */
/* e[63] is between 0 and 7 */
carry = 0;
for (i = 0; i < 63; ++i) {
e[i] += carry;
carry = e[i] + 8;
carry >>= 4;
e[i] -= carry << 4;
}
e[63] += carry;
/* each e[i] is between -8 and 8 */
ge_p3_0(h);
for (i = 1; i < 64; i += 2) {
select(&t, i / 2, e[i]);
ge_madd(&r, h, &t);
ge_p1p1_to_p3(h, &r);
}
ge_p3_dbl(&r, h);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p3(h, &r);
for (i = 0; i < 64; i += 2) {
select(&t, i / 2, e[i]);
ge_madd(&r, h, &t);
ge_p1p1_to_p3(h, &r);
}
}
/*
r = p - q
*/
void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0;
fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->YminusX);
fe_mul(r->Y, r->Y, q->YplusX);
fe_mul(r->T, q->T2d, p->T);
fe_mul(r->X, p->Z, q->Z);
fe_add(t0, r->X, r->X);
fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y);
fe_sub(r->Z, t0, r->T);
fe_add(r->T, t0, r->T);
}
void ge_tobytes(unsigned char *s, const ge_p2 *h) {
fe recip;
fe x;
fe y;
fe_invert(recip, h->Z);
fe_mul(x, h->X, recip);
fe_mul(y, h->Y, recip);
fe_tobytes(s, y);
s[31] ^= fe_isnegative(x) << 7;
}

View File

@@ -1,74 +0,0 @@
#ifndef GE_H
#define GE_H
#include "fe.h"
/*
ge means group element.
Here the group is the set of pairs (x,y) of field elements (see fe.h)
satisfying -x^2 + y^2 = 1 + d x^2y^2
where d = -121665/121666.
Representations:
ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
ge_precomp (Duif): (y+x,y-x,2dxy)
*/
typedef struct {
fe X;
fe Y;
fe Z;
} ge_p2;
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p3;
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p1p1;
typedef struct {
fe yplusx;
fe yminusx;
fe xy2d;
} ge_precomp;
typedef struct {
fe YplusX;
fe YminusX;
fe Z;
fe T2d;
} ge_cached;
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h);
void ge_tobytes(unsigned char *s, const ge_p2 *h);
int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s);
void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b);
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
void ge_scalarmult_base(ge_p3 *h, const unsigned char *a);
void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
void ge_p2_0(ge_p2 *h);
void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p);
void ge_p3_0(ge_p3 *h);
void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p);
void ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p);
#endif

View File

@@ -1,79 +0,0 @@
#include "ed25519.h"
#include "fe.h"
void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
unsigned char e[32];
unsigned int i;
fe x1;
fe x2;
fe z2;
fe x3;
fe z3;
fe tmp0;
fe tmp1;
int pos;
unsigned int swap;
unsigned int b;
/* copy the private key and make sure it's valid */
for (i = 0; i < 32; ++i) {
e[i] = private_key[i];
}
e[0] &= 248;
e[31] &= 63;
e[31] |= 64;
/* unpack the public key and convert edwards to montgomery */
/* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
fe_frombytes(x1, public_key);
fe_1(tmp1);
fe_add(tmp0, x1, tmp1);
fe_sub(tmp1, tmp1, x1);
fe_invert(tmp1, tmp1);
fe_mul(x1, tmp0, tmp1);
fe_1(x2);
fe_0(z2);
fe_copy(x3, x1);
fe_1(z3);
swap = 0;
for (pos = 254; pos >= 0; --pos) {
b = e[pos / 8] >> (pos & 7);
b &= 1;
swap ^= b;
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
swap = b;
/* from montgomery.h */
fe_sub(tmp0, x3, z3);
fe_sub(tmp1, x2, z2);
fe_add(x2, x2, z2);
fe_add(z2, x3, z3);
fe_mul(z3, tmp0, x2);
fe_mul(z2, z2, tmp1);
fe_sq(tmp0, tmp1);
fe_sq(tmp1, x2);
fe_add(x3, z3, z2);
fe_sub(z2, z3, z2);
fe_mul(x2, tmp1, tmp0);
fe_sub(tmp1, tmp1, tmp0);
fe_sq(z2, z2);
fe_mul121666(z3, tmp1);
fe_sq(x3, x3);
fe_add(tmp0, tmp0, z3);
fe_mul(z3, x1, z2);
fe_mul(z2, tmp1, tmp0);
}
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
fe_invert(z2, z2);
fe_mul(x2, x2, z2);
fe_tobytes(shared_secret, x2);
}

View File

@@ -1,16 +0,0 @@
#include "ed25519.h"
#include "sha512.h"
#include "ge.h"
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
ge_p3 A;
sha512(seed, 32, private_key);
private_key[0] &= 248;
private_key[31] &= 63;
private_key[31] |= 64;
ge_scalarmult_base(&A, private_key);
ge_p3_tobytes(public_key, &A);
}

View File

@@ -1,809 +0,0 @@
#include "fixedint.h"
#include "sc.h"
static uint64_t load_3(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
return result;
}
static uint64_t load_4(const unsigned char *in) {
uint64_t result;
result = (uint64_t) in[0];
result |= ((uint64_t) in[1]) << 8;
result |= ((uint64_t) in[2]) << 16;
result |= ((uint64_t) in[3]) << 24;
return result;
}
/*
Input:
s[0]+256*s[1]+...+256^63*s[63] = s
Output:
s[0]+256*s[1]+...+256^31*s[31] = s mod l
where l = 2^252 + 27742317777372353535851937790883648493.
Overwrites s in place.
*/
void sc_reduce(unsigned char *s) {
int64_t s0 = 2097151 & load_3(s);
int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
int64_t s8 = 2097151 & load_3(s + 21);
int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
int64_t s16 = 2097151 & load_3(s + 42);
int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
int64_t s23 = (load_4(s + 60) >> 3);
int64_t carry0;
int64_t carry1;
int64_t carry2;
int64_t carry3;
int64_t carry4;
int64_t carry5;
int64_t carry6;
int64_t carry7;
int64_t carry8;
int64_t carry9;
int64_t carry10;
int64_t carry11;
int64_t carry12;
int64_t carry13;
int64_t carry14;
int64_t carry15;
int64_t carry16;
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry11 = s11 >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s[0] = (unsigned char) (s0 >> 0);
s[1] = (unsigned char) (s0 >> 8);
s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5));
s[3] = (unsigned char) (s1 >> 3);
s[4] = (unsigned char) (s1 >> 11);
s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2));
s[6] = (unsigned char) (s2 >> 6);
s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7));
s[8] = (unsigned char) (s3 >> 1);
s[9] = (unsigned char) (s3 >> 9);
s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4));
s[11] = (unsigned char) (s4 >> 4);
s[12] = (unsigned char) (s4 >> 12);
s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1));
s[14] = (unsigned char) (s5 >> 7);
s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6));
s[16] = (unsigned char) (s6 >> 2);
s[17] = (unsigned char) (s6 >> 10);
s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3));
s[19] = (unsigned char) (s7 >> 5);
s[20] = (unsigned char) (s7 >> 13);
s[21] = (unsigned char) (s8 >> 0);
s[22] = (unsigned char) (s8 >> 8);
s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5));
s[24] = (unsigned char) (s9 >> 3);
s[25] = (unsigned char) (s9 >> 11);
s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2));
s[27] = (unsigned char) (s10 >> 6);
s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7));
s[29] = (unsigned char) (s11 >> 1);
s[30] = (unsigned char) (s11 >> 9);
s[31] = (unsigned char) (s11 >> 17);
}
/*
Input:
a[0]+256*a[1]+...+256^31*a[31] = a
b[0]+256*b[1]+...+256^31*b[31] = b
c[0]+256*c[1]+...+256^31*c[31] = c
Output:
s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
where l = 2^252 + 27742317777372353535851937790883648493.
*/
void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) {
int64_t a0 = 2097151 & load_3(a);
int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
int64_t a8 = 2097151 & load_3(a + 21);
int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
int64_t a11 = (load_4(a + 28) >> 7);
int64_t b0 = 2097151 & load_3(b);
int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
int64_t b8 = 2097151 & load_3(b + 21);
int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
int64_t b11 = (load_4(b + 28) >> 7);
int64_t c0 = 2097151 & load_3(c);
int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
int64_t c8 = 2097151 & load_3(c + 21);
int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
int64_t c11 = (load_4(c + 28) >> 7);
int64_t s0;
int64_t s1;
int64_t s2;
int64_t s3;
int64_t s4;
int64_t s5;
int64_t s6;
int64_t s7;
int64_t s8;
int64_t s9;
int64_t s10;
int64_t s11;
int64_t s12;
int64_t s13;
int64_t s14;
int64_t s15;
int64_t s16;
int64_t s17;
int64_t s18;
int64_t s19;
int64_t s20;
int64_t s21;
int64_t s22;
int64_t s23;
int64_t carry0;
int64_t carry1;
int64_t carry2;
int64_t carry3;
int64_t carry4;
int64_t carry5;
int64_t carry6;
int64_t carry7;
int64_t carry8;
int64_t carry9;
int64_t carry10;
int64_t carry11;
int64_t carry12;
int64_t carry13;
int64_t carry14;
int64_t carry15;
int64_t carry16;
int64_t carry17;
int64_t carry18;
int64_t carry19;
int64_t carry20;
int64_t carry21;
int64_t carry22;
s0 = c0 + a0 * b0;
s1 = c1 + a0 * b1 + a1 * b0;
s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0;
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4;
s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
s20 = a9 * b11 + a10 * b10 + a11 * b9;
s21 = a10 * b11 + a11 * b10;
s22 = a11 * b11;
s23 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
carry18 = (s18 + (1 << 20)) >> 21;
s19 += carry18;
s18 -= carry18 << 21;
carry20 = (s20 + (1 << 20)) >> 21;
s21 += carry20;
s20 -= carry20 << 21;
carry22 = (s22 + (1 << 20)) >> 21;
s23 += carry22;
s22 -= carry22 << 21;
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
carry17 = (s17 + (1 << 20)) >> 21;
s18 += carry17;
s17 -= carry17 << 21;
carry19 = (s19 + (1 << 20)) >> 21;
s20 += carry19;
s19 -= carry19 << 21;
carry21 = (s21 + (1 << 20)) >> 21;
s22 += carry21;
s21 -= carry21 << 21;
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry12 = (s12 + (1 << 20)) >> 21;
s13 += carry12;
s12 -= carry12 << 21;
carry14 = (s14 + (1 << 20)) >> 21;
s15 += carry14;
s14 -= carry14 << 21;
carry16 = (s16 + (1 << 20)) >> 21;
s17 += carry16;
s16 -= carry16 << 21;
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
carry13 = (s13 + (1 << 20)) >> 21;
s14 += carry13;
s13 -= carry13 << 21;
carry15 = (s15 + (1 << 20)) >> 21;
s16 += carry15;
s15 -= carry15 << 21;
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = (s0 + (1 << 20)) >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry2 = (s2 + (1 << 20)) >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry4 = (s4 + (1 << 20)) >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry6 = (s6 + (1 << 20)) >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry8 = (s8 + (1 << 20)) >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry10 = (s10 + (1 << 20)) >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry1 = (s1 + (1 << 20)) >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry3 = (s3 + (1 << 20)) >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry5 = (s5 + (1 << 20)) >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry7 = (s7 + (1 << 20)) >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry9 = (s9 + (1 << 20)) >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry11 = (s11 + (1 << 20)) >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
carry11 = s11 >> 21;
s12 += carry11;
s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21;
s1 += carry0;
s0 -= carry0 << 21;
carry1 = s1 >> 21;
s2 += carry1;
s1 -= carry1 << 21;
carry2 = s2 >> 21;
s3 += carry2;
s2 -= carry2 << 21;
carry3 = s3 >> 21;
s4 += carry3;
s3 -= carry3 << 21;
carry4 = s4 >> 21;
s5 += carry4;
s4 -= carry4 << 21;
carry5 = s5 >> 21;
s6 += carry5;
s5 -= carry5 << 21;
carry6 = s6 >> 21;
s7 += carry6;
s6 -= carry6 << 21;
carry7 = s7 >> 21;
s8 += carry7;
s7 -= carry7 << 21;
carry8 = s8 >> 21;
s9 += carry8;
s8 -= carry8 << 21;
carry9 = s9 >> 21;
s10 += carry9;
s9 -= carry9 << 21;
carry10 = s10 >> 21;
s11 += carry10;
s10 -= carry10 << 21;
s[0] = (unsigned char) (s0 >> 0);
s[1] = (unsigned char) (s0 >> 8);
s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5));
s[3] = (unsigned char) (s1 >> 3);
s[4] = (unsigned char) (s1 >> 11);
s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2));
s[6] = (unsigned char) (s2 >> 6);
s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7));
s[8] = (unsigned char) (s3 >> 1);
s[9] = (unsigned char) (s3 >> 9);
s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4));
s[11] = (unsigned char) (s4 >> 4);
s[12] = (unsigned char) (s4 >> 12);
s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1));
s[14] = (unsigned char) (s5 >> 7);
s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6));
s[16] = (unsigned char) (s6 >> 2);
s[17] = (unsigned char) (s6 >> 10);
s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3));
s[19] = (unsigned char) (s7 >> 5);
s[20] = (unsigned char) (s7 >> 13);
s[21] = (unsigned char) (s8 >> 0);
s[22] = (unsigned char) (s8 >> 8);
s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5));
s[24] = (unsigned char) (s9 >> 3);
s[25] = (unsigned char) (s9 >> 11);
s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2));
s[27] = (unsigned char) (s10 >> 6);
s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7));
s[29] = (unsigned char) (s11 >> 1);
s[30] = (unsigned char) (s11 >> 9);
s[31] = (unsigned char) (s11 >> 17);
}

View File

@@ -1,12 +0,0 @@
#ifndef SC_H
#define SC_H
/*
The set of scalars is \Z/l
where l = 2^252 + 27742317777372353535851937790883648493.
*/
void sc_reduce(unsigned char *s);
void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c);
#endif

View File

@@ -1,40 +0,0 @@
#include "ed25519.h"
#ifndef ED25519_NO_SEED
#ifdef _WIN32
#include <windows.h>
#include <wincrypt.h>
#else
#include <stdio.h>
#endif
int ed25519_create_seed(unsigned char *seed) {
#ifdef _WIN32
HCRYPTPROV prov;
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
return 1;
}
if (!CryptGenRandom(prov, 32, seed)) {
CryptReleaseContext(prov, 0);
return 1;
}
CryptReleaseContext(prov, 0);
#else
FILE *f = fopen("/dev/urandom", "rb");
if (f == NULL) {
return 1;
}
fread(seed, 1, 32, f);
fclose(f);
#endif
return 0;
}
#endif

View File

@@ -1,275 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "fixedint.h"
#include "sha512.h"
/* the K array */
static const uint64_t K[80] = {
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
};
/* Various logical functions */
#define ROR64c(x, y) \
( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \
((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF))
#define STORE64H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
#define LOAD64H(x, y) \
{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64c(x, n)
#define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n))
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
#ifndef MIN
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
#endif
/* compress 1024-bits */
static int sha512_compress(sha512_context *md, unsigned char *buf)
{
uint64_t S[8], W[80], t0, t1;
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->state[i];
}
/* copy the state into 1024-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD64H(W[i], buf + (8*i));
}
/* fill W[16..79] */
for (i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c);\
d += t0; \
h = t0 + t1;
for (i = 0; i < 80; i += 8) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
}
#undef RND
/* feedback */
for (i = 0; i < 8; i++) {
md->state[i] = md->state[i] + S[i];
}
return 0;
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return 0 if successful
*/
int sha512_init(sha512_context * md) {
if (md == NULL) return 1;
md->curlen = 0;
md->length = 0;
md->state[0] = UINT64_C(0x6a09e667f3bcc908);
md->state[1] = UINT64_C(0xbb67ae8584caa73b);
md->state[2] = UINT64_C(0x3c6ef372fe94f82b);
md->state[3] = UINT64_C(0xa54ff53a5f1d36f1);
md->state[4] = UINT64_C(0x510e527fade682d1);
md->state[5] = UINT64_C(0x9b05688c2b3e6c1f);
md->state[6] = UINT64_C(0x1f83d9abfb41bd6b);
md->state[7] = UINT64_C(0x5be0cd19137e2179);
return 0;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return 0 if successful
*/
int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
{
size_t n;
size_t i;
int err;
if (md == NULL) return 1;
if (in == NULL) return 1;
if (md->curlen > sizeof(md->buf)) {
return 1;
}
while (inlen > 0) {
if (md->curlen == 0 && inlen >= 128) {
if ((err = sha512_compress (md, (unsigned char *)in)) != 0) {
return err;
}
md->length += 128 * 8;
in += 128;
inlen -= 128;
} else {
n = MIN(inlen, (128 - md->curlen));
for (i = 0; i < n; i++) {
md->buf[i + md->curlen] = in[i];
}
md->curlen += n;
in += n;
inlen -= n;
if (md->curlen == 128) {
if ((err = sha512_compress (md, md->buf)) != 0) {
return err;
}
md->length += 8*128;
md->curlen = 0;
}
}
}
return 0;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (64 bytes)
@return 0 if successful
*/
int sha512_final(sha512_context * md, unsigned char *out)
{
int i;
if (md == NULL) return 1;
if (out == NULL) return 1;
if (md->curlen >= sizeof(md->buf)) {
return 1;
}
/* increase the length of the message */
md->length += md->curlen * UINT64_C(8);
/* append the '1' bit */
md->buf[md->curlen++] = (unsigned char)0x80;
/* if the length is currently above 112 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->curlen > 112) {
while (md->curlen < 128) {
md->buf[md->curlen++] = (unsigned char)0;
}
sha512_compress(md, md->buf);
md->curlen = 0;
}
/* pad upto 120 bytes of zeroes
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
* > 2^64 bits of data... :-)
*/
while (md->curlen < 120) {
md->buf[md->curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->length, md->buf+120);
sha512_compress(md, md->buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE64H(md->state[i], out+(8*i));
}
return 0;
}
int sha512(const unsigned char *message, size_t message_len, unsigned char *out)
{
sha512_context ctx;
int ret;
if ((ret = sha512_init(&ctx))) return ret;
if ((ret = sha512_update(&ctx, message, message_len))) return ret;
if ((ret = sha512_final(&ctx, out))) return ret;
return 0;
}

View File

@@ -1,21 +0,0 @@
#ifndef SHA512_H
#define SHA512_H
#include <stddef.h>
#include "fixedint.h"
/* state */
typedef struct sha512_context_ {
uint64_t length, state[8];
size_t curlen;
unsigned char buf[128];
} sha512_context;
int sha512_init(sha512_context * md);
int sha512_final(sha512_context * md, unsigned char *out);
int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen);
int sha512(const unsigned char *message, size_t message_len, unsigned char *out);
#endif

View File

@@ -1,31 +0,0 @@
#include "ed25519.h"
#include "sha512.h"
#include "ge.h"
#include "sc.h"
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
sha512_context hash;
unsigned char hram[64];
unsigned char r[64];
ge_p3 R;
sha512_init(&hash);
sha512_update(&hash, private_key + 32, 32);
sha512_update(&hash, message, message_len);
sha512_final(&hash, r);
sc_reduce(r);
ge_scalarmult_base(&R, r);
ge_p3_tobytes(signature, &R);
sha512_init(&hash);
sha512_update(&hash, signature, 32);
sha512_update(&hash, public_key, 32);
sha512_update(&hash, message, message_len);
sha512_final(&hash, hram);
sc_reduce(hram);
sc_muladd(signature + 32, hram, private_key, r);
}

View File

@@ -1,77 +0,0 @@
#include "ed25519.h"
#include "sha512.h"
#include "ge.h"
#include "sc.h"
static int consttime_equal(const unsigned char *x, const unsigned char *y) {
unsigned char r = 0;
r = x[0] ^ y[0];
#define F(i) r |= x[i] ^ y[i]
F(1);
F(2);
F(3);
F(4);
F(5);
F(6);
F(7);
F(8);
F(9);
F(10);
F(11);
F(12);
F(13);
F(14);
F(15);
F(16);
F(17);
F(18);
F(19);
F(20);
F(21);
F(22);
F(23);
F(24);
F(25);
F(26);
F(27);
F(28);
F(29);
F(30);
F(31);
#undef F
return !r;
}
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
unsigned char h[64];
unsigned char checker[32];
sha512_context hash;
ge_p3 A;
ge_p2 R;
if (signature[63] & 224) {
return 0;
}
if (ge_frombytes_negate_vartime(&A, public_key) != 0) {
return 0;
}
sha512_init(&hash);
sha512_update(&hash, signature, 32);
sha512_update(&hash, public_key, 32);
sha512_update(&hash, message, message_len);
sha512_final(&hash, h);
sc_reduce(h);
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
ge_tobytes(checker, &R);
if (!consttime_equal(checker, signature)) {
return 0;
}
return 1;
}

View File

@@ -1,62 +0,0 @@
Licensing
---------
SRP is royalty-free worldwide for commercial and non-commercial use.
The SRP library has been carefully written not to depend on any
encumbered algorithms, and it is distributed under a standard
BSD-style Open Source license which is shown below. This license
covers implementations based on the SRP library as well as
independent implementations based on RFC 2945.
The SRP distribution itself contains algorithms and code from
various freeware packages; these parts fall under both the SRP
Open Source license and the packages' own licenses. Care has
been taken to ensure that these licenses are compatible with
Open Source distribution, but it is the responsibility of the
licensee to comply with the terms of these licenses. This
disclaimer also applies to third-party libraries that may be
linked into the distribution, since they may contain patented
intellectual property. The file "Copyrights" contains a list
of the copyrights incorporated by portions of the software.
Broader use of the SRP authentication technology, such as variants
incorporating the use of an explicit server secret (SRP-Z), may
require a license; please contact the Stanford Office of Technology
Licensing (http://otl.stanford.edu/) for more information about
terms and conditions.
This software is covered under the following copyright:
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
Address all questions regarding this license to:
Tom Wu
tjw@cs.Stanford.EDU

View File

@@ -1,31 +0,0 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir) \
-Wno-incompatible-pointer-types
include_HEADERS = srp.h srp_aux.h cstr.h
AM_CFLAGS = -DHAVE_CONFIG_H
if HAVE_OPENSSL
AM_CFLAGS += -DOPENSSL=1 $(openssl_CFLAGS)
else
if HAVE_GCRYPT
AM_CFLAGS += -DGCRYPT=1 $(libgcrypt_CFLAGS)
else
if HAVE_MBEDTLS
AM_CFLAGS += -DMBEDTLS=1 $(mbedtls_CFLAGS)
endif
endif
endif
noinst_LTLIBRARIES = libsrp6a-sha512.la
libsrp6a_sha512_la_SOURCES = \
t_conv.c t_math.c t_misc.c \
t_truerand.c cstr.c \
srp.c srp6a_sha512_client.c
if !HAVE_OPENSSL
libsrp6a_sha512_la_SOURCES += t_sha.c
endif

View File

@@ -1,35 +0,0 @@
# SRP6a-sha512 library
## About
This library is based on Stanford's Secure Remote Password (SRP) protocol
implementation, or more precise on the `libsrp` part thereof.
The entire source code for the SRP project can be obtained from [here](https://github.com/secure-remote-password/stanford-srp).
It has been adapted to the needs of the libimobiledevice project, and
contains just a part of the original code; it only supports the SRP6a
client method which has been modified to use SHA512 instead of SHA1.
The only supported SRP method is `SRP6a_sha512_client_method()`.
Besides that, support for MbedTLS has been added.
Also, all server-side code has been removed, and the client-side code
has been reduced to a minimum, so that basically only the following
functions remain operational:
- `SRP_initialize_library`
- `SRP_new`
- `SRP_free`
- `SRP_set_user_raw`
- `SRP_set_params`
- `SRP_set_auth_password`
- `SRP_gen_pub`
- `SRP_compute_key`
- `SRP_respond`
- `SRP_verify`
Anything else has not been tested and must be considered non-functional.
## License
The license of the original work does still apply and can be found in the
LICENSE file that comes with the code.

View File

@@ -1,226 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "cstr.h"
#define EXPFACTOR 2 /* Minimum expansion factor */
#define MINSIZE 4 /* Absolute minimum - one word */
static char cstr_empty_string[] = { '\0' };
static cstr_allocator * default_alloc = NULL;
/*
* It is assumed, for efficiency, that it is okay to pass more arguments
* to a function than are called for, as long as the required arguments
* are in proper form. If extra arguments to malloc() and free() cause
* problems, define PEDANTIC_ARGS below.
*/
#ifdef PEDANTIC_ARGS
static void * Cmalloc(int n, void * heap) { return malloc(n); }
static void Cfree(void * p, void * heap) { free(p); }
static cstr_allocator malloc_allocator = { Cmalloc, Cfree, NULL };
#else
static cstr_allocator malloc_allocator = { malloc, free, NULL };
#endif
_TYPE( void )
cstr_set_allocator(cstr_allocator * alloc)
{
default_alloc = alloc;
}
_TYPE( cstr * )
cstr_new_alloc(cstr_allocator * alloc)
{
cstr * str;
if(alloc == NULL) {
if(default_alloc == NULL) {
default_alloc = &malloc_allocator;
}
alloc = default_alloc;
}
str = (cstr *) (*alloc->alloc)(sizeof(cstr), alloc->heap);
if(str) {
str->data = cstr_empty_string;
str->length = str->cap = 0;
str->ref = 1;
str->allocator = alloc;
}
return str;
}
_TYPE( cstr * )
cstr_new()
{
return cstr_new_alloc(NULL);
}
_TYPE( cstr * )
cstr_dup_alloc(const cstr * str, cstr_allocator * alloc)
{
cstr * nstr = cstr_new_alloc(alloc);
if(nstr)
cstr_setn(nstr, str->data, str->length);
return nstr;
}
_TYPE( cstr * )
cstr_dup(const cstr * str)
{
return cstr_dup_alloc(str, NULL);
}
_TYPE( cstr * )
cstr_create(const char * s)
{
return cstr_createn(s, strlen(s));
}
_TYPE( cstr * )
cstr_createn(const char * s, int len)
{
cstr * str = cstr_new();
if(str) {
cstr_setn(str, s, len);
}
return str;
}
_TYPE( void )
cstr_use(cstr * str)
{
++str->ref;
}
_TYPE( void )
cstr_clear_free(cstr * str)
{
if(--str->ref == 0) {
if(str->cap > 0) {
memset(str->data, 0, str->cap);
(*str->allocator->free)(str->data, str->allocator->heap);
}
(*str->allocator->free)(str, str->allocator->heap);
}
}
_TYPE( void )
cstr_free(cstr * str)
{
if(--str->ref == 0) {
if(str->cap > 0)
(*str->allocator->free)(str->data, str->allocator->heap);
(*str->allocator->free)(str, str->allocator->heap);
}
}
_TYPE( void )
cstr_empty(cstr * str)
{
if(str->cap > 0)
(*str->allocator->free)(str->data, str->allocator->heap);
str->data = cstr_empty_string;
str->length = str->cap = 0;
}
static int
cstr_alloc(cstr * str, int len)
{
char * t;
if(len > str->cap) {
if(len < EXPFACTOR * str->cap)
len = EXPFACTOR * str->cap;
if(len < MINSIZE)
len = MINSIZE;
t = (char *) (*str->allocator->alloc)(len * sizeof(char),
str->allocator->heap);
if(t) {
if(str->data) {
t[str->length] = 0;
if(str->cap > 0) {
if(str->length > 0)
memcpy(t, str->data, str->length);
free(str->data);
}
}
str->data = t;
str->cap = len;
return 1;
}
else
return -1;
}
else
return 0;
}
_TYPE( int )
cstr_copy(cstr * dst, const cstr * src)
{
return cstr_setn(dst, src->data, src->length);
}
_TYPE( int )
cstr_set(cstr * str, const char * s)
{
return cstr_setn(str, s, strlen(s));
}
_TYPE( int )
cstr_setn(cstr * str, const char * s, int len)
{
if(cstr_alloc(str, len + 1) < 0)
return -1;
str->data[len] = 0;
if(s != NULL && len > 0)
memmove(str->data, s, len);
str->length = len;
return 1;
}
_TYPE( int )
cstr_set_length(cstr * str, int len)
{
if(len < str->length) {
str->data[len] = 0;
str->length = len;
return 1;
}
else if(len > str->length) {
if(cstr_alloc(str, len + 1) < 0)
return -1;
memset(str->data + str->length, 0, len - str->length + 1);
str->length = len;
return 1;
}
else
return 0;
}
_TYPE( int )
cstr_append(cstr * str, const char * s)
{
return cstr_appendn(str, s, strlen(s));
}
_TYPE( int )
cstr_appendn(cstr * str, const char * s, int len)
{
if(cstr_alloc(str, str->length + len + 1) < 0)
return -1;
memcpy(str->data + str->length, s, len);
str->length += len;
str->data[str->length] = 0;
return 1;
}
_TYPE( int )
cstr_append_str(cstr * dst, const cstr * src)
{
return cstr_appendn(dst, src->data, src->length);
}

View File

@@ -1,94 +0,0 @@
#ifndef _CSTR_H_
#define _CSTR_H_
/* A general-purpose string "class" for C */
#if !defined(P)
#ifdef __STDC__
#define P(x) x
#else
#define P(x) ()
#endif
#endif
/* For building dynamic link libraries under windows, windows NT
* using MSVC1.5 or MSVC2.0
*/
#ifndef _DLLDECL
#define _DLLDECL
#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
#define _MSVC15EXPORT _export
#define _MSVC20EXPORT
#define _DLLAPI _export _pascal
#define _CDECL
#define _TYPE(a) a _MSVC15EXPORT
#define DLLEXPORT 1
#elif defined(MSVC20) || (defined(_USRDLL) && defined(SRP_EXPORTS))
#define _MSVC15EXPORT
#define _MSVC20EXPORT _declspec(dllexport)
#define _DLLAPI
#define _CDECL
#define _TYPE(a) _MSVC20EXPORT a
#define DLLEXPORT 1
#else /* Default, non-dll. Use this for Unix or DOS */
#define _MSVC15DEXPORT
#define _MSVC20EXPORT
#define _DLLAPI
#if defined(WINDOWS) || defined(WIN32)
#define _CDECL _cdecl
#else
#define _CDECL
#endif
#define _TYPE(a) a _CDECL
#endif
#endif /* _DLLDECL */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Arguments to allocator methods ordered this way for compatibility */
typedef struct cstr_alloc_st {
void * (_CDECL * alloc)(size_t n, void * heap);
void (_CDECL * free)(void * p, void * heap);
void * heap;
} cstr_allocator;
typedef struct cstr_st {
char * data; /* Okay to access data and length fields directly */
int length;
int cap;
int ref; /* Simple reference counter */
cstr_allocator * allocator;
} cstr;
_TYPE( void ) cstr_set_allocator P((cstr_allocator * alloc));
_TYPE( cstr * ) cstr_new P((void));
_TYPE( cstr * ) cstr_new_alloc P((cstr_allocator * alloc));
_TYPE( cstr * ) cstr_dup P((const cstr * str));
_TYPE( cstr * ) cstr_dup_alloc P((const cstr * str, cstr_allocator * alloc));
_TYPE( cstr * ) cstr_create P((const char * s));
_TYPE( cstr * ) cstr_createn P((const char * s, int len));
_TYPE( void ) cstr_free P((cstr * str));
_TYPE( void ) cstr_clear_free P((cstr * str));
_TYPE( void ) cstr_use P((cstr * str));
_TYPE( void ) cstr_empty P((cstr * str));
_TYPE( int ) cstr_copy P((cstr * dst, const cstr * src));
_TYPE( int ) cstr_set P((cstr * str, const char * s));
_TYPE( int ) cstr_setn P((cstr * str, const char * s, int len));
_TYPE( int ) cstr_set_length P((cstr * str, int len));
_TYPE( int ) cstr_append P((cstr * str, const char * s));
_TYPE( int ) cstr_appendn P((cstr * str, const char * s, int len));
_TYPE( int ) cstr_append_str P((cstr * dst, const cstr * src));
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CSTR_H_ */

View File

@@ -1,274 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#include "t_defines.h"
#include "srp.h"
static int library_initialized = 0;
_TYPE( SRP_RESULT )
SRP_initialize_library()
{
if(library_initialized == 0) {
BigIntegerInitialize();
t_stronginitrand();
library_initialized = 1;
}
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_finalize_library()
{
if(library_initialized > 0) {
library_initialized = 0;
BigIntegerFinalize();
}
return SRP_SUCCESS;
}
static int srp_modulus_min_bits = SRP_DEFAULT_MIN_BITS;
_TYPE( SRP_RESULT )
SRP_set_modulus_min_bits(int minbits)
{
srp_modulus_min_bits = minbits;
return SRP_SUCCESS;
}
_TYPE( int )
SRP_get_modulus_min_bits()
{
return srp_modulus_min_bits;
}
static int
default_secret_bits_cb(int modsize)
{
return 256;
/*return modsize;*/ /* Warning: Very Slow */
}
static SRP_SECRET_BITS_CB srp_sb_cb = default_secret_bits_cb;
_TYPE( SRP_RESULT )
SRP_set_secret_bits_cb(SRP_SECRET_BITS_CB cb)
{
srp_sb_cb = cb;
return SRP_SUCCESS;
}
_TYPE( int )
SRP_get_secret_bits(int modsize)
{
return (*srp_sb_cb)(modsize);
}
_TYPE( SRP * )
SRP_new(SRP_METHOD * meth)
{
SRP * srp = (SRP *) malloc(sizeof(SRP));
if(srp == NULL)
return NULL;
srp->flags = 0;
srp->username = cstr_new();
srp->bctx = BigIntegerCtxNew();
srp->modulus = NULL;
srp->accel = NULL;
srp->generator = NULL;
srp->salt = NULL;
srp->verifier = NULL;
srp->password = NULL;
srp->pubkey = NULL;
srp->secret = NULL;
srp->u = NULL;
srp->key = NULL;
srp->ex_data = cstr_new();
srp->param_cb = NULL;
srp->meth = meth;
srp->meth_data = NULL;
//srp->slu = NULL;
if(srp->meth->init == NULL || (*srp->meth->init)(srp) == SRP_SUCCESS)
return srp;
free(srp);
return NULL;
}
_TYPE( SRP_RESULT )
SRP_free(SRP * srp)
{
if(srp->meth->finish)
(*srp->meth->finish)(srp);
if(srp->username)
cstr_clear_free(srp->username);
if(srp->modulus)
BigIntegerFree(srp->modulus);
if(srp->accel)
BigIntegerModAccelFree(srp->accel);
if(srp->generator)
BigIntegerFree(srp->generator);
if(srp->salt)
cstr_clear_free(srp->salt);
if(srp->verifier)
BigIntegerClearFree(srp->verifier);
if(srp->password)
BigIntegerClearFree(srp->password);
if(srp->pubkey)
BigIntegerFree(srp->pubkey);
if(srp->secret)
BigIntegerClearFree(srp->secret);
if(srp->u)
BigIntegerFree(srp->u);
if(srp->key)
BigIntegerClearFree(srp->key);
if(srp->bctx)
BigIntegerCtxFree(srp->bctx);
if(srp->ex_data)
cstr_clear_free(srp->ex_data);
free(srp);
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_set_client_param_verify_cb(SRP * srp, SRP_CLIENT_PARAM_VERIFY_CB cb)
{
srp->param_cb = cb;
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_set_username(SRP * srp, const char * username)
{
cstr_set(srp->username, username);
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_set_user_raw(SRP * srp, const unsigned char * user, int userlen)
{
cstr_setn(srp->username, (const char*)user, userlen);
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_set_params(SRP * srp, const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen)
{
SRP_RESULT rc;
if(modulus == NULL || generator == NULL || salt == NULL)
return SRP_ERROR;
/* Set fields in SRP context */
srp->modulus = BigIntegerFromBytes(modulus, modlen);
if(srp->flags & SRP_FLAG_MOD_ACCEL)
srp->accel = BigIntegerModAccelNew(srp->modulus, srp->bctx);
srp->generator = BigIntegerFromBytes(generator, genlen);
if(srp->salt == NULL)
srp->salt = cstr_new();
cstr_setn(srp->salt, (const char*)salt, saltlen);
/* Now attempt to validate parameters */
if(BigIntegerBitLen(srp->modulus) < SRP_get_modulus_min_bits())
return SRP_ERROR;
if(srp->param_cb) {
rc = (*srp->param_cb)(srp, modulus, modlen, generator, genlen);
if(!SRP_OK(rc))
return rc;
}
return (*srp->meth->params)(srp, modulus, modlen, generator, genlen,
salt, saltlen);
}
_TYPE( SRP_RESULT )
SRP_set_authenticator(SRP * srp, const unsigned char * a, int alen)
{
return (*srp->meth->auth)(srp, a, alen);
}
_TYPE( SRP_RESULT )
SRP_set_auth_password(SRP * srp, const char * password)
{
return (*srp->meth->passwd)(srp, (const unsigned char *)password,
strlen(password));
}
_TYPE( SRP_RESULT )
SRP_set_auth_password_raw(SRP * srp,
const unsigned char * password, int passlen)
{
return (*srp->meth->passwd)(srp, password, passlen);
}
_TYPE( SRP_RESULT )
SRP_gen_pub(SRP * srp, cstr ** result)
{
return (*srp->meth->genpub)(srp, result);
}
_TYPE( SRP_RESULT )
SRP_add_ex_data(SRP * srp, const unsigned char * data, int datalen)
{
cstr_appendn(srp->ex_data, (const char*)data, datalen);
return SRP_SUCCESS;
}
_TYPE( SRP_RESULT )
SRP_compute_key(SRP * srp, cstr ** result,
const unsigned char * pubkey, int pubkeylen)
{
return (*srp->meth->key)(srp, result, pubkey, pubkeylen);
}
_TYPE( SRP_RESULT )
SRP_verify(SRP * srp, const unsigned char * proof, int prooflen)
{
return (*srp->meth->verify)(srp, proof, prooflen);
}
_TYPE( SRP_RESULT )
SRP_respond(SRP * srp, cstr ** proof)
{
return (*srp->meth->respond)(srp, proof);
}
_TYPE( SRP_RESULT )
SRP_use_engine(const char * engine)
{
if(BigIntegerOK(BigIntegerUseEngine(engine)))
return SRP_SUCCESS;
else
return SRP_ERROR;
}

View File

@@ -1,372 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#ifndef _SRP_H_
#define _SRP_H_
#include "cstr.h"
#include "srp_aux.h"
#ifdef __cplusplus
extern "C" {
#endif
/* SRP library version identification */
#define SRP_VERSION_MAJOR 2
#define SRP_VERSION_MINOR 0
#define SRP_VERSION_PATCHLEVEL 1
typedef int SRP_RESULT;
/* Returned codes for SRP API functions */
#define SRP_OK(v) ((v) == SRP_SUCCESS)
#define SRP_SUCCESS 0
#define SRP_ERROR -1
/* Set the minimum number of bits acceptable in an SRP modulus */
#define SRP_DEFAULT_MIN_BITS 512
_TYPE( SRP_RESULT ) SRP_set_modulus_min_bits P((int minbits));
_TYPE( int ) SRP_get_modulus_min_bits P((void));
/*
* Sets the "secret size callback" function.
* This function is called with the modulus size in bits,
* and returns the size of the secret exponent in bits.
* The default function always returns 256 bits.
*/
typedef int (_CDECL * SRP_SECRET_BITS_CB)(int modsize);
_TYPE( SRP_RESULT ) SRP_set_secret_bits_cb P((SRP_SECRET_BITS_CB cb));
_TYPE( int ) SRP_get_secret_bits P((int modsize));
typedef struct srp_st SRP;
#if 0
/* Server Lookup API */
typedef struct srp_server_lu_st SRP_SERVER_LOOKUP;
typedef struct srp_s_lu_meth_st {
const char * name;
SRP_RESULT (_CDECL * init)(SRP_SERVER_LOOKUP * slu);
SRP_RESULT (_CDECL * finish)(SRP_SERVER_LOOKUP * slu);
SRP_RESULT (_CDECL * lookup)(SRP_SERVER_LOOKUP * slu, SRP * srp, cstr * username);
void * meth_data;
} SRP_SERVER_LOOKUP_METHOD;
struct srp_server_lu_st {
SRP_SERVER_LOOKUP_METHOD * meth;
void * data;
};
/*
* The Server Lookup API deals with the server-side issue of
* mapping usernames to verifiers. Given a username, a lookup
* mechanism needs to provide parameters (N, g), salt (s), and
* password verifier (v) for that user.
*
* A SRP_SERVER_LOOKUP_METHOD describes the general mechanism
* for performing lookups (e.g. files, LDAP, database, etc.)
* A SRP_SERVER_LOOKUP is an active "object" that is actually
* called to do lookups.
*/
_TYPE( SRP_SERVER_LOOKUP * )
SRP_SERVER_LOOKUP_new P((SRP_SERVER_LOOKUP_METHOD * meth));
_TYPE( SRP_RESULT ) SRP_SERVER_LOOKUP_free P((SRP_SERVER_LOOKUP * slu));
_TYPE( SRP_RESULT ) SRP_SERVER_do_lookup P((SRP_SERVER_LOOKUP * slu,
SRP * srp, cstr * username));
/*
* SRP_SERVER_system_lookup supercedes SRP_server_init_user.
*/
_TYPE( SRP_SERVER_LOOKUP * ) SRP_SERVER_system_lookup P((void));
#endif
/*
* Client Parameter Verification API
*
* This callback is called from the SRP client when the
* parameters (modulus and generator) are set. The callback
* should return SRP_SUCCESS if the parameters are okay,
* otherwise some error code to indicate that the parameters
* should be rejected.
*/
typedef SRP_RESULT (_CDECL * SRP_CLIENT_PARAM_VERIFY_CB)(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
#if 0
/* The default parameter verifier function */
_TYPE( SRP_RESULT ) SRP_CLIENT_default_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
/* A parameter verifier that only accepts builtin params (no prime test) */
_TYPE( SRP_RESULT ) SRP_CLIENT_builtin_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
/* The "classic" parameter verifier that accepts either builtin params
* immediately, and performs safe-prime tests on N and primitive-root
* tests on g otherwise. SECURITY WARNING: This may allow for certain
* attacks based on "trapdoor" moduli, so this is not recommended. */
_TYPE( SRP_RESULT ) SRP_CLIENT_compat_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
#endif
/*
* Main SRP API - SRP and SRP_METHOD
*/
/* SRP method definitions */
typedef struct srp_meth_st {
const char * name;
SRP_RESULT (_CDECL * init)(SRP * srp);
SRP_RESULT (_CDECL * finish)(SRP * srp);
SRP_RESULT (_CDECL * params)(SRP * srp,
const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen);
SRP_RESULT (_CDECL * auth)(SRP * srp, const unsigned char * a, int alen);
SRP_RESULT (_CDECL * passwd)(SRP * srp,
const unsigned char * pass, int passlen);
SRP_RESULT (_CDECL * genpub)(SRP * srp, cstr ** result);
SRP_RESULT (_CDECL * key)(SRP * srp, cstr ** result,
const unsigned char * pubkey, int pubkeylen);
SRP_RESULT (_CDECL * verify)(SRP * srp,
const unsigned char * proof, int prooflen);
SRP_RESULT (_CDECL * respond)(SRP * srp, cstr ** proof);
void * data;
} SRP_METHOD;
/* Magic numbers for the SRP context header */
#define SRP_MAGIC_CLIENT 12
#define SRP_MAGIC_SERVER 28
/* Flag bits for SRP struct */
#define SRP_FLAG_MOD_ACCEL 0x1 /* accelerate modexp operations */
#define SRP_FLAG_LEFT_PAD 0x2 /* left-pad to length-of-N inside hashes */
/*
* A hybrid structure that represents either client or server state.
*/
struct srp_st {
int magic; /* To distinguish client from server (and for sanity) */
int flags;
cstr * username;
BigInteger modulus;
BigInteger generator;
cstr * salt;
BigInteger verifier;
BigInteger password;
BigInteger pubkey;
BigInteger secret;
BigInteger u;
BigInteger key;
cstr * ex_data;
SRP_METHOD * meth;
void * meth_data;
BigIntegerCtx bctx; /* to cache temporaries if available */
BigIntegerModAccel accel; /* to accelerate modexp if available */
SRP_CLIENT_PARAM_VERIFY_CB param_cb; /* to verify params */
//SRP_SERVER_LOOKUP * slu; /* to look up users */
};
/*
* Global initialization/de-initialization functions.
* Call SRP_initialize_library before using the library,
* and SRP_finalize_library when done.
*/
_TYPE( SRP_RESULT ) SRP_initialize_library();
_TYPE( SRP_RESULT ) SRP_finalize_library();
/*
* SRP_new() creates a new SRP context object -
* the method determines which "sense" (client or server)
* the object operates in. SRP_free() frees it.
* (See RFC2945 method definitions below.)
*/
_TYPE( SRP * ) SRP_new P((SRP_METHOD * meth));
_TYPE( SRP_RESULT ) SRP_free P((SRP * srp));
#if 0
/*
* Use the supplied lookup object to look up user parameters and
* password verifier. The lookup function gets called during
* SRP_set_username/SRP_set_user_raw below. Using this function
* means that the server can avoid calling SRP_set_params and
* SRP_set_authenticator, since the lookup function handles that
* internally.
*/
_TYPE( SRP_RESULT ) SRP_set_server_lookup P((SRP * srp,
SRP_SERVER_LOOKUP * lookup));
#endif
/*
* Use the supplied callback function to verify parameters
* (modulus, generator) given to the client.
*/
_TYPE( SRP_RESULT )
SRP_set_client_param_verify_cb P((SRP * srp,
SRP_CLIENT_PARAM_VERIFY_CB cb));
/*
* Both client and server must call both SRP_set_username and
* SRP_set_params, in that order, before calling anything else.
* SRP_set_user_raw is an alternative to SRP_set_username that
* accepts an arbitrary length-bounded octet string as input.
*/
_TYPE( SRP_RESULT ) SRP_set_username P((SRP * srp, const char * username));
_TYPE( SRP_RESULT ) SRP_set_user_raw P((SRP * srp, const unsigned char * user,
int userlen));
_TYPE( SRP_RESULT )
SRP_set_params P((SRP * srp,
const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen));
/*
* On the client, SRP_set_authenticator, SRP_gen_exp, and
* SRP_add_ex_data can be called in any order.
* On the server, SRP_set_authenticator must come first,
* followed by SRP_gen_exp and SRP_add_ex_data in either order.
*/
/*
* The authenticator is the secret possessed by either side.
* For the server, this is the bigendian verifier, as an octet string.
* For the client, this is the bigendian raw secret, as an octet string.
* The server's authenticator must be the generator raised to the power
* of the client's raw secret modulo the common modulus for authentication
* to succeed.
*
* SRP_set_auth_password computes the authenticator from a plaintext
* password and then calls SRP_set_authenticator automatically. This is
* usually used on the client side, while the server usually uses
* SRP_set_authenticator (since it doesn't know the plaintext password).
*/
_TYPE( SRP_RESULT )
SRP_set_authenticator P((SRP * srp, const unsigned char * a, int alen));
_TYPE( SRP_RESULT )
SRP_set_auth_password P((SRP * srp, const char * password));
_TYPE( SRP_RESULT )
SRP_set_auth_password_raw P((SRP * srp,
const unsigned char * password,
int passlen));
/*
* SRP_gen_pub generates the random exponential residue to send
* to the other side. If using SRP-3/RFC2945, the server must
* withhold its result until it receives the client's number.
* If using SRP-6, the server can send its value immediately
* without waiting for the client.
*
* If "result" points to a NULL pointer, a new cstr object will be
* created to hold the result, and "result" will point to it.
* If "result" points to a non-NULL cstr pointer, the result will be
* placed there.
* If "result" itself is NULL, no result will be returned,
* although the big integer value will still be available
* through srp->pubkey in the SRP struct.
*/
_TYPE( SRP_RESULT ) SRP_gen_pub P((SRP * srp, cstr ** result));
/*
* Append the data to the extra data segment. Authentication will
* not succeed unless both sides add precisely the same data in
* the same order.
*/
_TYPE( SRP_RESULT ) SRP_add_ex_data P((SRP * srp, const unsigned char * data,
int datalen));
/*
* SRP_compute_key must be called after the previous three methods.
*/
_TYPE( SRP_RESULT ) SRP_compute_key P((SRP * srp, cstr ** result,
const unsigned char * pubkey,
int pubkeylen));
/*
* On the client, call SRP_respond first to get the response to send
* to the server, and call SRP_verify to verify the server's response.
* On the server, call SRP_verify first to verify the client's response,
* and call SRP_respond ONLY if verification succeeds.
*
* It is an error to call SRP_respond with a NULL pointer.
*/
_TYPE( SRP_RESULT ) SRP_verify P((SRP * srp,
const unsigned char * proof, int prooflen));
_TYPE( SRP_RESULT ) SRP_respond P((SRP * srp, cstr ** response));
/* RFC2945-style SRP authentication */
#define RFC2945_KEY_LEN 40 /* length of session key (bytes) */
#define RFC2945_RESP_LEN 20 /* length of proof hashes (bytes) */
/*
* RFC2945-style SRP authentication methods. Use these like:
* SRP * srp = SRP_new(SRP_RFC2945_client_method());
*/
_TYPE( SRP_METHOD * ) SRP_RFC2945_client_method P((void));
_TYPE( SRP_METHOD * ) SRP_RFC2945_server_method P((void));
/*
* SRP-6 and SRP-6a authentication methods.
* SRP-6a is recommended for better resistance to 2-for-1 attacks.
*/
_TYPE( SRP_METHOD * ) SRP6_client_method P((void));
_TYPE( SRP_METHOD * ) SRP6_server_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_client_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_server_method P((void));
_TYPE( SRP_METHOD * ) SRP6a_sha512_client_method P((void));
/*
* Convenience function - SRP_server_init_user
* Looks up the username from the system EPS configuration and calls
* SRP_set_username, SRP_set_params, and SRP_set_authenticator to
* initialize server state for that user.
*
* This is deprecated in favor of SRP_SERVER_system_lookup() and
* the Server Lookup API.
*/
_TYPE( SRP_RESULT ) SRP_server_init_user P((SRP * srp, const char * username));
/*
* Use the named engine for acceleration.
*/
_TYPE( SRP_RESULT ) SRP_use_engine P((const char * engine));
#ifdef __cplusplus
}
#endif
#endif /* _SRP_H_ */

View File

@@ -1,363 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#include "t_defines.h"
#include "srp.h"
#include "t_sha.h"
/*
* SRP-6/6a has two minor refinements relative to SRP-3/RFC2945:
* 1. The "g^x" value is multipled by three in the client's
* calculation of its session key.
* SRP-6a: The "g^x" value is multiplied by the hash of
* N and g in the client's session key calculation.
* 2. The value of u is taken as the hash of A and B,
* instead of the top 32 bits of the hash of B.
* This eliminates the old restriction where the
* server had to receive A before it could send B.
*/
/****************************/
#define SHA512_DIGESTSIZE 64
#define SRP6_SHA512_KEY_LEN 64
/*
* The client keeps track of the running hash
* state via SHA512_CTX structures pointed to by the
* meth_data pointer. The "hash" member is the hash value that
* will be sent to the other side; the "ckhash" member is the
* hash value expected from the other side.
*/
struct sha512_client_meth_st {
SHA512_CTX hash;
SHA512_CTX ckhash;
unsigned char k[SRP6_SHA512_KEY_LEN];
};
#define SHA512_CLIENT_CTXP(srp) ((struct sha512_client_meth_st *)(srp)->meth_data)
static SRP_RESULT
srp6a_sha512_client_init(SRP * srp)
{
srp->magic = SRP_MAGIC_CLIENT;
srp->flags = SRP_FLAG_MOD_ACCEL | SRP_FLAG_LEFT_PAD;
srp->meth_data = malloc(sizeof(struct sha512_client_meth_st));
SHA512Init(&SHA512_CLIENT_CTXP(srp)->hash);
SHA512Init(&SHA512_CLIENT_CTXP(srp)->ckhash);
return SRP_SUCCESS;
}
static SRP_RESULT
srp6_sha512_client_finish(SRP * srp)
{
if(srp->meth_data) {
memset(srp->meth_data, 0, sizeof(struct sha512_client_meth_st));
free(srp->meth_data);
}
return SRP_SUCCESS;
}
static SRP_RESULT
srp6_sha512_client_params(SRP * srp, const unsigned char * modulus, int modlen,
const unsigned char * generator, int genlen,
const unsigned char * salt, int saltlen)
{
int i;
unsigned char buf1[SHA512_DIGESTSIZE], buf2[SHA512_DIGESTSIZE];
SHA512_CTX ctxt;
/* Fields set by SRP_set_params */
/* Update hash state */
SHA512Init(&ctxt);
SHA512Update(&ctxt, modulus, modlen);
SHA512Final(buf1, &ctxt); /* buf1 = H(modulus) */
SHA512Init(&ctxt);
SHA512Update(&ctxt, generator, genlen);
SHA512Final(buf2, &ctxt); /* buf2 = H(generator) */
for(i = 0; i < sizeof(buf1); ++i)
buf1[i] ^= buf2[i]; /* buf1 = H(modulus) xor H(generator) */
/* hash: H(N) xor H(g) */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, buf1, sizeof(buf1));
SHA512Init(&ctxt);
SHA512Update(&ctxt, srp->username->data, srp->username->length);
SHA512Final(buf1, &ctxt); /* buf1 = H(user) */
/* hash: (H(N) xor H(g)) | H(U) */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, buf1, sizeof(buf1));
/* hash: (H(N) xor H(g)) | H(U) | s */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, salt, saltlen);
return SRP_SUCCESS;
}
static SRP_RESULT
srp6_sha512_client_auth(SRP * srp, const unsigned char * a, int alen)
{
/* On the client, the authenticator is the raw password-derived hash */
srp->password = BigIntegerFromBytes(a, alen);
/* verifier = g^x mod N */
srp->verifier = BigIntegerFromInt(0);
BigIntegerModExp(srp->verifier, srp->generator, srp->password, srp->modulus, srp->bctx, srp->accel);
return SRP_SUCCESS;
}
static SRP_RESULT
srp6_sha512_client_passwd(SRP * srp, const unsigned char * p, int plen)
{
SHA512_CTX ctxt;
unsigned char dig[SHA512_DIGESTSIZE];
int r;
SHA512Init(&ctxt);
SHA512Update(&ctxt, srp->username->data, srp->username->length);
SHA512Update(&ctxt, ":", 1);
SHA512Update(&ctxt, p, plen);
SHA512Final(dig, &ctxt); /* dig = H(U | ":" | P) */
SHA512Init(&ctxt);
SHA512Update(&ctxt, srp->salt->data, srp->salt->length);
SHA512Update(&ctxt, dig, sizeof(dig));
SHA512Final(dig, &ctxt); /* dig = H(s | H(U | ":" | P)) */
memset(&ctxt, 0, sizeof(ctxt));
r = SRP_set_authenticator(srp, dig, sizeof(dig));
memset(dig, 0, sizeof(dig));
return r;
}
static SRP_RESULT
srp6_sha512_client_genpub(SRP * srp, cstr ** result)
{
cstr * astr;
int slen = (SRP_get_secret_bits(BigIntegerBitLen(srp->modulus)) + 7) / 8;
if(result == NULL)
astr = cstr_new();
else {
if(*result == NULL)
*result = cstr_new();
astr = *result;
}
cstr_set_length(astr, BigIntegerByteLen(srp->modulus));
t_random((unsigned char*)astr->data, slen);
srp->secret = BigIntegerFromBytes((const unsigned char*)astr->data, slen);
/* Force g^a mod n to "wrap around" by adding log[2](n) to "a". */
BigIntegerAddInt(srp->secret, srp->secret, BigIntegerBitLen(srp->modulus));
/* A = g^a mod n */
srp->pubkey = BigIntegerFromInt(0);
BigIntegerModExp(srp->pubkey, srp->generator, srp->secret, srp->modulus, srp->bctx, srp->accel);
BigIntegerToCstr(srp->pubkey, astr);
/* hash: (H(N) xor H(g)) | H(U) | s | A */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, astr->data, astr->length);
/* ckhash: A */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, astr->data, astr->length);
if(result == NULL) /* astr was a temporary */
cstr_clear_free(astr);
return SRP_SUCCESS;
}
static SRP_RESULT
srp6_sha512_client_key_ex(SRP * srp, cstr ** result,
const unsigned char * pubkey, int pubkeylen, BigInteger k)
{
SHA512_CTX ctxt;
unsigned char dig[SHA512_DIGESTSIZE];
BigInteger gb, e;
cstr * s;
int modlen;
modlen = BigIntegerByteLen(srp->modulus);
if(pubkeylen > modlen)
return SRP_ERROR;
/* Compute u from client's and server's values */
SHA512Init(&ctxt);
/* Use s as a temporary to store client's value */
s = cstr_new();
if(srp->flags & SRP_FLAG_LEFT_PAD) {
BigIntegerToCstrEx(srp->pubkey, s, modlen);
SHA512Update(&ctxt, s->data, s->length);
if(pubkeylen < modlen) {
memcpy(s->data + (modlen - pubkeylen), pubkey, pubkeylen);
memset(s->data, 0, modlen - pubkeylen);
SHA512Update(&ctxt, s->data, modlen);
}
else
SHA512Update(&ctxt, pubkey, pubkeylen);
}
else {
BigIntegerToCstr(srp->pubkey, s);
SHA512Update(&ctxt, s->data, s->length);
SHA512Update(&ctxt, pubkey, pubkeylen);
}
SHA512Final(dig, &ctxt);
srp->u = BigIntegerFromBytes(dig, SHA512_DIGESTSIZE);
/* hash: (H(N) xor H(g)) | H(U) | s | A | B */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, pubkey, pubkeylen);
gb = BigIntegerFromBytes(pubkey, pubkeylen);
/* reject B == 0, B >= modulus */
if(BigIntegerCmp(gb, srp->modulus) >= 0 || BigIntegerCmpInt(gb, 0) == 0) {
BigIntegerFree(gb);
cstr_clear_free(s);
return SRP_ERROR;
}
e = BigIntegerFromInt(0);
srp->key = BigIntegerFromInt(0);
/* unblind g^b (mod N) */
BigIntegerSub(srp->key, srp->modulus, srp->verifier);
/* use e as temporary, e == -k*v (mod N) */
BigIntegerMul(e, k, srp->key, srp->bctx);
BigIntegerAdd(e, e, gb);
BigIntegerMod(gb, e, srp->modulus, srp->bctx);
/* compute gb^(a + ux) (mod N) */
BigIntegerMul(e, srp->password, srp->u, srp->bctx);
BigIntegerAdd(e, e, srp->secret); /* e = a + ux */
BigIntegerModExp(srp->key, gb, e, srp->modulus, srp->bctx, srp->accel);
BigIntegerClearFree(e);
BigIntegerClearFree(gb);
/* convert srp->key into a session key, update hash states */
BigIntegerToCstr(srp->key, s);
SHA512Init(&ctxt);
SHA512Update(&ctxt, s->data, s->length);
SHA512Final((unsigned char*)&SHA512_CLIENT_CTXP(srp)->k, &ctxt);
cstr_clear_free(s);
/* hash: (H(N) xor H(g)) | H(U) | s | A | B | K */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
/* hash: (H(N) xor H(g)) | H(U) | s | A | B | K | ex_data */
if(srp->ex_data->length > 0)
SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash,
srp->ex_data->data, srp->ex_data->length);
if(result) {
if(*result == NULL)
*result = cstr_new();
cstr_setn(*result, (const char*)SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
}
return SRP_SUCCESS;
}
static SRP_RESULT
srp6a_sha512_client_key(SRP * srp, cstr ** result,
const unsigned char * pubkey, int pubkeylen)
{
SRP_RESULT ret;
BigInteger k;
cstr * s;
SHA512_CTX ctxt;
unsigned char dig[SHA512_DIGESTSIZE];
SHA512Init(&ctxt);
s = cstr_new();
BigIntegerToCstr(srp->modulus, s);
SHA512Update(&ctxt, s->data, s->length);
if(srp->flags & SRP_FLAG_LEFT_PAD)
BigIntegerToCstrEx(srp->generator, s, s->length);
else
BigIntegerToCstr(srp->generator, s);
SHA512Update(&ctxt, s->data, s->length);
SHA512Final(dig, &ctxt);
cstr_free(s);
k = BigIntegerFromBytes(dig, SHA512_DIGESTSIZE);
if(BigIntegerCmpInt(k, 0) == 0)
ret = SRP_ERROR;
else
ret = srp6_sha512_client_key_ex(srp, result, pubkey, pubkeylen, k);
BigIntegerClearFree(k);
return ret;
}
static SRP_RESULT
srp6_sha512_client_verify(SRP * srp, const unsigned char * proof, int prooflen)
{
unsigned char expected[SHA512_DIGESTSIZE];
SHA512Final(expected, &SHA512_CLIENT_CTXP(srp)->ckhash);
if(prooflen == SHA512_DIGESTSIZE && memcmp(expected, proof, prooflen) == 0)
return SRP_SUCCESS;
else
return SRP_ERROR;
}
static SRP_RESULT
srp6_sha512_client_respond(SRP * srp, cstr ** proof)
{
if(proof == NULL)
return SRP_ERROR;
if(*proof == NULL)
*proof = cstr_new();
/* proof contains client's response */
cstr_set_length(*proof, SHA512_DIGESTSIZE);
SHA512Final((unsigned char*)(*proof)->data, &SHA512_CLIENT_CTXP(srp)->hash);
/* ckhash: A | M | K */
SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, (*proof)->data, (*proof)->length);
SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
return SRP_SUCCESS;
}
static SRP_METHOD srp6a_sha512_client_meth = {
"SRP-6a sha512 client (tjw)",
srp6a_sha512_client_init,
srp6_sha512_client_finish,
srp6_sha512_client_params,
srp6_sha512_client_auth,
srp6_sha512_client_passwd,
srp6_sha512_client_genpub,
srp6a_sha512_client_key,
srp6_sha512_client_verify,
srp6_sha512_client_respond,
NULL
};
_TYPE( SRP_METHOD * )
SRP6a_sha512_client_method()
{
return &srp6a_sha512_client_meth;
}

View File

@@ -1,146 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#ifndef SRP_AUX_H
#define SRP_AUX_H
#include "cstr.h"
#ifdef __cplusplus
extern "C" {
#endif
/* BigInteger abstraction API */
#ifndef MATH_PRIV
typedef void * BigInteger;
typedef void * BigIntegerCtx;
typedef void * BigIntegerModAccel;
#endif
/*
* Some functions return a BigIntegerResult.
* Use BigIntegerOK to test for success.
*/
#define BIG_INTEGER_SUCCESS 0
#define BIG_INTEGER_ERROR -1
#define BigIntegerOK(v) ((v) == BIG_INTEGER_SUCCESS)
typedef int BigIntegerResult;
_TYPE( BigInteger ) BigIntegerFromInt P((unsigned int number));
_TYPE( BigInteger ) BigIntegerFromBytes P((const unsigned char * bytes,
int length));
#define BigIntegerByteLen(X) ((BigIntegerBitLen(X)+7)/8)
_TYPE( int ) BigIntegerToBytes P((BigInteger src,
unsigned char * dest, int destlen));
_TYPE( BigIntegerResult ) BigIntegerToCstr P((BigInteger src, cstr * dest));
_TYPE( BigIntegerResult ) BigIntegerToCstrEx P((BigInteger src, cstr * dest, int len));
_TYPE( BigIntegerResult ) BigIntegerToHex P((BigInteger src,
char * dest, int destlen));
_TYPE( BigIntegerResult ) BigIntegerToString P((BigInteger src,
char * dest, int destlen,
unsigned int radix));
_TYPE( int ) BigIntegerBitLen P((BigInteger b));
_TYPE( int ) BigIntegerCmp P((BigInteger c1, BigInteger c2));
_TYPE( int ) BigIntegerCmpInt P((BigInteger c1, unsigned int c2));
_TYPE( BigIntegerResult ) BigIntegerLShift P((BigInteger result, BigInteger x,
unsigned int bits));
_TYPE( BigIntegerResult ) BigIntegerAdd P((BigInteger result,
BigInteger a1, BigInteger a2));
_TYPE( BigIntegerResult ) BigIntegerAddInt P((BigInteger result,
BigInteger a1, unsigned int a2));
_TYPE( BigIntegerResult ) BigIntegerSub P((BigInteger result,
BigInteger s1, BigInteger s2));
_TYPE( BigIntegerResult ) BigIntegerSubInt P((BigInteger result,
BigInteger s1, unsigned int s2));
/* For BigIntegerMul{,Int}: result != m1, m2 */
_TYPE( BigIntegerResult ) BigIntegerMul P((BigInteger result, BigInteger m1,
BigInteger m2, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerMulInt P((BigInteger result,
BigInteger m1, unsigned int m2,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerDivInt P((BigInteger result,
BigInteger d, unsigned int m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerMod P((BigInteger result, BigInteger d,
BigInteger m, BigIntegerCtx ctx));
_TYPE( unsigned int ) BigIntegerModInt P((BigInteger d, unsigned int m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModMul P((BigInteger result,
BigInteger m1, BigInteger m2,
BigInteger m, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModExp P((BigInteger result,
BigInteger base, BigInteger expt,
BigInteger modulus,
BigIntegerCtx ctx,
BigIntegerModAccel accel));
_TYPE( int ) BigIntegerCheckPrime P((BigInteger n, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerFree P((BigInteger b));
_TYPE( BigIntegerResult ) BigIntegerClearFree P((BigInteger b));
_TYPE( BigIntegerCtx ) BigIntegerCtxNew();
_TYPE( BigIntegerResult ) BigIntegerCtxFree P((BigIntegerCtx ctx));
_TYPE( BigIntegerModAccel ) BigIntegerModAccelNew P((BigInteger m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModAccelFree P((BigIntegerModAccel accel));
_TYPE( BigIntegerResult ) BigIntegerInitialize();
_TYPE( BigIntegerResult ) BigIntegerFinalize();
_TYPE( BigIntegerResult ) BigIntegerUseEngine P((const char * engine));
_TYPE( BigIntegerResult ) BigIntegerReleaseEngine();
/* Miscellaneous functions - formerly in t_pwd.h */
/*
* "t_random" is a cryptographic random number generator, which is seeded
* from various high-entropy sources and uses a one-way hash function
* in a feedback configuration.
* "t_sessionkey" is the interleaved hash used to generate session keys
* from a large integer.
* "t_mgf1" is an implementation of MGF1 using SHA1 to generate session
* keys from large integers, and is preferred over the older
* interleaved hash, and is used with SRP6.
* "t_getpass" reads a password from the terminal without echoing.
*/
_TYPE( void ) t_random P((unsigned char *, unsigned));
_TYPE( void ) t_stronginitrand();
_TYPE( unsigned char * )
t_sessionkey P((unsigned char *, unsigned char *, unsigned));
_TYPE( void ) t_mgf1 P((unsigned char *, unsigned,
const unsigned char *, unsigned));
_TYPE( int ) t_getpass P((char *, unsigned, const char *));
#ifdef __cplusplus
}
#endif
#endif /* SRP_AUX_H */

View File

@@ -1,258 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
/*#define _POSIX_SOURCE*/
#include <stdio.h>
#include "t_defines.h"
#include "cstr.h"
static int
hexDigitToInt(c)
char c;
{
if(c >= '0' && c <= '9')
return c - '0';
else if(c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if(c >= 'A' && c <= 'F')
return c - 'A' + 10;
else
return 0;
}
/*
* Convert a hex string to a string of bytes; return size of dst
*/
_TYPE( int )
t_fromhex(dst, src)
char * dst;
const char * src;
{
register char *chp = dst;
register unsigned size = strlen(src);
/* FIXME: handle whitespace and non-hex digits by setting size and src
appropriately. */
if(size % 2 == 1) {
*chp++ = hexDigitToInt(*src++);
--size;
}
while(size > 0) {
*chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
src += 2;
size -= 2;
}
return chp - dst;
}
/*
* Convert a string of bytes to their hex representation
*/
_TYPE( char * )
t_tohex(dst, src, size)
char * dst;
const char * src;
unsigned size;
{
int notleading = 0;
register char *chp = dst;
*dst = '\0';
if (size != 0) do {
if(notleading || *src != '\0') {
if(!notleading && (*src & 0xf0) == 0) {
sprintf(chp, "%.1X", * (unsigned char *) src);
chp += 1;
}
else {
sprintf(chp, "%.2X", * (unsigned char *) src);
chp += 2;
}
notleading = 1;
}
++src;
} while (--size != 0);
return dst;
}
_TYPE( char * )
t_tohexcstr(dst, src, size)
cstr * dst;
const char * src;
unsigned size;
{
cstr_set_length(dst, 2 * size + 1);
return t_tohex(dst->data, src, size);
}
static char b64table[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
/*
* Convert a base64 string into raw byte array representation.
*/
_TYPE( int )
t_fromb64(dst, src)
char * dst;
const char * src;
{
unsigned char *a;
char *loc;
int i, j;
unsigned int size;
while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
++src;
size = strlen(src);
a = malloc((size + 1) * sizeof(unsigned char));
if(a == (unsigned char *) 0)
return -1;
i = 0;
while(i < size) {
loc = strchr(b64table, src[i]);
if(loc == (char *) 0)
break;
else
a[i] = loc - b64table;
++i;
}
size = i;
i = size - 1;
j = size;
while(1) {
a[j] = a[i];
if(--i < 0)
break;
a[j] |= (a[i] & 3) << 6;
--j;
a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
if(--i < 0)
break;
a[j] |= (a[i] & 0xf) << 4;
--j;
a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
if(--i < 0)
break;
a[j] |= (a[i] << 2);
a[--j] = 0;
if(--i < 0)
break;
}
while(a[j] == 0 && j <= size)
++j;
memcpy(dst, a + j, size - j + 1);
free(a);
return size - j + 1;
}
_TYPE( int )
t_cstrfromb64(dst, src)
cstr * dst;
const char * src;
{
int len;
cstr_set_length(dst, (strlen(src) * 6 + 7) / 8);
len = t_fromb64(dst->data, src);
cstr_set_length(dst, len);
return len;
}
/*
* Convert a raw byte string into a null-terminated base64 ASCII string.
*/
_TYPE( char * )
t_tob64(dst, src, size)
char * dst;
const char * src;
unsigned size;
{
int c, pos = size % 3;
unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
char *olddst = dst;
switch(pos) {
case 1:
b2 = src[0];
break;
case 2:
b1 = src[0];
b2 = src[1];
break;
}
while(1) {
c = (b0 & 0xfc) >> 2;
if(notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
if(notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
if(notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
c = b2 & 0x3f;
if(notleading || c != 0) {
*dst++ = b64table[c];
notleading = 1;
}
if(pos >= size)
break;
else {
b0 = src[pos++];
b1 = src[pos++];
b2 = src[pos++];
}
}
*dst++ = '\0';
return olddst;
}
_TYPE( char * )
t_tob64cstr(dst, src, sz)
cstr * dst;
const char * src;
unsigned int sz;
{
cstr_set_length(dst, (sz * 8 + 5) / 6 + 1);
return t_tob64(dst->data, src, sz);
}

View File

@@ -1,137 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#ifndef T_DEFINES_H
#define T_DEFINES_H
#ifndef P
#if defined(__STDC__) || defined(__cplusplus)
#define P(x) x
#else
#define P(x) ()
#endif
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifndef _DLLDECL
#define _DLLDECL
#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
#define _MSVC15EXPORT _export
#define _MSVC20EXPORT
#define _DLLAPI _export _pascal
#define _CDECL
#define _TYPE(a) a _MSVC15EXPORT
#define DLLEXPORT 1
#elif defined(MSVC20) || (defined(_USRDLL) && defined(SRP_EXPORTS))
#define _MSVC15EXPORT
#define _MSVC20EXPORT _declspec(dllexport)
#define _DLLAPI
#define _CDECL
#define _TYPE(a) _MSVC20EXPORT a
#define DLLEXPORT 1
#else /* Default, non-dll. Use this for Unix or DOS */
#define _MSVC15DEXPORT
#define _MSVC20EXPORT
#define _DLLAPI
#if defined(WINDOWS) || defined(WIN32)
#define _CDECL _cdecl
#else
#define _CDECL
#endif
#define _TYPE(a) a _CDECL
#endif
#endif
#if STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#else /* not STDC_HEADERS */
#ifndef HAVE_STRCHR
#define strchr index
#define strrchr rindex
#endif
char *strchr(), *strrchr(), *strtok();
#ifndef HAVE_MEMCPY
#define memcpy(d, s, n) bcopy((s), (d), (n))
#endif
#endif /* not STDC_HEADERS */
#include <sys/types.h>
#if TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else /* not TIME_WITH_SYS_TIME */
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif /* not TIME_WITH_SYS_TIME */
#if HAVE_TERMIOS_H
#include <termios.h>
#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
#define GTTY(fd, termio) tcgetattr(fd, termio)
#define TERMIO struct termios
#define USE_TERMIOS
#elif HAVE_TERMIO_H
#include <sys/ioctl.h>
#include <termio.h>
#define STTY(fd, termio) ioctl(fd, TCSETA, termio)
#define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
#define TEMRIO struct termio
#define USE_TERMIO
#elif HAVE_SGTTY_H
#include <sgtty.h>
#define STTY(fd, termio) stty(fd, termio)
#define GTTY(fd, termio) gtty(fd, termio)
#define TERMIO struct sgttyb
#define USE_SGTTY
#endif
#ifdef WIN32
#define USE_FTIME 1
#define USE_RENAME 1
#define NO_FCHMOD 1
#endif
#ifdef USE_FTIME
#include <sys/timeb.h>
#endif
/* Looking for BigInteger math functions? They've moved to <srp_aux.h>. */
#endif

View File

@@ -1,450 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#include "t_defines.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef WIN32
#include <process.h>
#include <io.h>
#endif
#include "t_sha.h"
#ifndef NULL
#define NULL 0
#endif
#ifdef OPENSSL
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#elif defined(TOMCRYPT)
#include "tomcrypt.h"
static prng_state g_rng;
static unsigned char entropy[32];
#elif defined(CRYPTOLIB)
# include "libcrypt.h"
static unsigned char crpool[64];
#else
static unsigned char randpool[SHA_DIGESTSIZE], randout[SHA_DIGESTSIZE];
static unsigned long randcnt = 0;
static unsigned int outpos = 0;
SHA1_CTX randctxt;
#endif /* OPENSSL */
/*
* t_envhash - Generate a 160-bit SHA hash of the environment
*
* This routine performs an SHA hash of all the "name=value" pairs
* in the environment concatenated together and dumps them in the
* output. While it is true that anyone on the system can see
* your environment, someone not on the system will have a very
* difficult time guessing it, especially since some systems play
* tricks with variable ordering and sometimes define quirky
* environment variables like $WINDOWID or $_.
*/
extern char ** environ;
static void
t_envhash(out)
unsigned char * out;
{
char ** ptr;
char ebuf[256];
SHA1_CTX ctxt;
SHA1Init(&ctxt);
for(ptr = environ; *ptr; ++ptr) {
strncpy(ebuf, *ptr, 255);
ebuf[255] = '\0';
SHA1Update(&ctxt, ebuf, strlen(ebuf));
}
SHA1Final(out, &ctxt);
}
/*
* t_fshash - Generate a 160-bit SHA hash from the file system
*
* This routine climbs up the directory tree from the current
* directory, running stat() on each directory until it hits the
* root directory. This information is sensitive to the last
* access/modification times of all the directories above you,
* so someone who lists one of those directories injects some
* entropy into the system. Obviously, this hash is very sensitive
* to your current directory when the program is run.
*
* For good measure, it also performs an fstat on the standard input,
* usually your tty, throws that into the buffer, creates a file in
* /tmp (the inode is unpredictable on a busy system), and runs stat()
* on that before deleting it.
*
* The entire buffer is run once through SHA to obtain the final result.
*/
static void
t_fshash(out)
unsigned char * out;
{
char dotpath[128];
struct stat st;
SHA1_CTX ctxt;
int i, pinode;
dev_t pdev;
SHA1Init(&ctxt);
if(stat(".", &st) >= 0) {
SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
pinode = st.st_ino;
pdev = st.st_dev;
strcpy(dotpath, "..");
for(i = 0; i < 40; ++i) {
if(stat(dotpath, &st) < 0)
break;
if(st.st_ino == pinode && st.st_dev == pdev)
break;
SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
pinode = st.st_ino;
pdev = st.st_dev;
strcat(dotpath, "/..");
}
}
if(fstat(0, &st) >= 0)
SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
sprintf(dotpath, "/tmp/rnd.%d", getpid());
if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
unlink(dotpath);
SHA1Final(out, &ctxt);
}
/*
* Generate a high-entropy seed for the strong random number generator.
* This uses a wide variety of quickly gathered and somewhat unpredictable
* system information. The 'preseed' structure is assembled from:
*
* The system time in seconds
* The system time in microseconds
* The current process ID
* The parent process ID
* A hash of the user's environment
* A hash gathered from the file system
* Input from a random device, if available
* Timings of system interrupts
*
* The entire structure (60 bytes on most systems) is fed to SHA to produce
* a 160-bit seed for the strong random number generator. It is believed
* that in the worst case (on a quiet system with no random device versus
* an attacker who has access to the system already), the seed contains at
* least about 80 bits of entropy. Versus an attacker who does not have
* access to the system, the entropy should be slightly over 128 bits.
*/
static char initialized = 0;
static struct {
unsigned int trand1;
time_t sec;
time_t subsec;
short pid;
short ppid;
unsigned char envh[SHA_DIGESTSIZE];
unsigned char fsh[SHA_DIGESTSIZE];
unsigned char devrand[20];
unsigned int trand2;
} preseed;
unsigned long raw_truerand();
static void
t_initrand()
{
SHA1_CTX ctxt;
#ifdef USE_FTIME
struct timeb t;
#else
struct timeval t;
#endif
int i, r=0;
if(initialized)
return;
initialized = 1;
#if defined(OPENSSL) /* OpenSSL has nifty win32 entropy-gathering code */
#if OPENSSL_VERSION_NUMBER >= 0x00905100
r = RAND_status();
#if defined(WINDOWS) || defined(WIN32)
if(r) /* Don't do the Unix-y stuff on Windows if possible */
return;
#else
#endif
#endif
#elif defined(TOMCRYPT)
yarrow_start(&g_rng);
r = rng_get_bytes(entropy, sizeof(entropy), NULL);
if(r > 0) {
yarrow_add_entropy(entropy, r, &g_rng);
memset(entropy, 0, sizeof(entropy));
# if defined(WINDOWS) || defined(WIN32)
/* Don't do the Unix-y stuff on Windows if possible */
yarrow_ready(&g_rng);
return;
# endif
}
#endif
#if !defined(WINDOWS) && !defined(WIN32)
i = open("/dev/urandom", O_RDONLY);
if(i > 0) {
r += read(i, preseed.devrand, sizeof(preseed.devrand));
close(i);
}
#endif /* !WINDOWS && !WIN32 */
/* Resort to truerand only if desperate for some Real entropy */
if(r == 0)
preseed.trand1 = raw_truerand();
#ifdef USE_FTIME
ftime(&t);
preseed.sec = t.time;
preseed.subsec = t.millitm;
#else
gettimeofday(&t, NULL);
preseed.sec = t.tv_sec;
preseed.subsec = t.tv_usec;
#endif
preseed.pid = getpid();
#ifndef WIN32
preseed.ppid = getppid();
#endif
t_envhash(preseed.envh);
t_fshash(preseed.fsh);
if(r == 0)
preseed.trand2 = raw_truerand();
#ifdef OPENSSL
RAND_seed((unsigned char *)&preseed, sizeof(preseed));
#elif defined(TOMCRYPT)
yarrow_add_entropy((unsigned char *)&preseed, sizeof(preseed), &g_rng);
yarrow_ready(&g_rng);
#elif defined(CRYPTOLIB)
t_mgf1(crpool, sizeof(crpool), (unsigned char *) &preseed, sizeof(preseed));
seedDesRandom(crpool, sizeof(crpool));
memset(crpool, 0, sizeof(crpool));
#elif defined(GCRYPT)
gcry_random_add_bytes((unsigned char *)&preseed, sizeof(preseed), -1);
#else
SHA1Init(&ctxt);
SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
SHA1Final(randpool, &ctxt);
memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
outpos = 0;
#endif /* OPENSSL */
memset((unsigned char *) &preseed, 0, sizeof(preseed));
}
#define NUM_RANDOMS 12
_TYPE( void )
t_stronginitrand()
{
#if 1 /* t_initrand() has been improved enough to make this unnecessary */
t_initrand();
#else
SHA1_CTX ctxt;
unsigned int rawrand[NUM_RANDOMS];
int i;
if(!initialized)
t_initrand();
for(i = 0; i < NUM_RANDOMS; ++i)
rawrand[i] = raw_truerand();
SHA1Init(&ctxt);
SHA1Update(&ctxt, (unsigned char *) rawrand, sizeof(rawrand));
SHA1Final(randkey2, &ctxt);
memset(rawrand, 0, sizeof(rawrand));
#endif
}
/*
* The strong random number generator. This uses a 160-bit seed
* and uses SHA-1 in a feedback configuration to generate successive
* outputs. If S[0] is set to the initial seed, then:
*
* S[i+1] = SHA-1(i || S[i])
* A[i] = SHA-1(S[i])
*
* where the A[i] are the output blocks starting with i=0.
* Each cycle generates 20 bytes of new output.
*/
_TYPE( void )
t_random(data, size)
unsigned char * data;
unsigned size;
{
if(!initialized)
t_initrand();
if(size <= 0) /* t_random(NULL, 0) forces seed initialization */
return;
#ifdef OPENSSL
RAND_bytes(data, size);
#elif defined(TOMCRYPT)
yarrow_read(data, size, &g_rng);
#elif defined(GCRYPT)
gcry_randomize(data, size, GCRY_STRONG_RANDOM);
#elif defined(CRYPTOLIB)
randomBytes(data, size, PSEUDO);
#else
while(size > outpos) {
if(outpos > 0) {
memcpy(data, randout + (sizeof(randout) - outpos), outpos);
data += outpos;
size -= outpos;
}
/* Recycle */
SHA1Init(&randctxt);
SHA1Update(&randctxt, randpool, sizeof(randpool));
SHA1Final(randout, &randctxt);
SHA1Init(&randctxt);
SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
SHA1Update(&randctxt, randpool, sizeof(randpool));
SHA1Final(randpool, &randctxt);
++randcnt;
outpos = sizeof(randout);
}
if(size > 0) {
memcpy(data, randout + (sizeof(randout) - outpos), size);
outpos -= size;
}
#endif
}
/*
* The interleaved session-key hash. This separates the even and the odd
* bytes of the input (ignoring the first byte if the input length is odd),
* hashes them separately, and re-interleaves the two outputs to form a
* single 320-bit value.
*/
_TYPE( unsigned char * )
t_sessionkey(key, sk, sklen)
unsigned char * key;
unsigned char * sk;
unsigned sklen;
{
unsigned i, klen;
unsigned char * hbuf;
unsigned char hout[SHA_DIGESTSIZE];
SHA1_CTX ctxt;
while(sklen > 0 && *sk == 0) { /* Skip leading 0's */
--sklen;
++sk;
}
klen = sklen / 2;
if((hbuf = malloc(klen * sizeof(char))) == 0)
return 0;
for(i = 0; i < klen; ++i)
hbuf[i] = sk[sklen - 2 * i - 1];
SHA1Init(&ctxt);
SHA1Update(&ctxt, hbuf, klen);
SHA1Final(hout, &ctxt);
for(i = 0; i < sizeof(hout); ++i)
key[2 * i] = hout[i];
for(i = 0; i < klen; ++i)
hbuf[i] = sk[sklen - 2 * i - 2];
SHA1Init(&ctxt);
SHA1Update(&ctxt, hbuf, klen);
SHA1Final(hout, &ctxt);
for(i = 0; i < sizeof(hout); ++i)
key[2 * i + 1] = hout[i];
memset(hout, 0, sizeof(hout));
memset(hbuf, 0, klen);
free(hbuf);
return key;
}
_TYPE( void )
t_mgf1(mask, masklen, seed, seedlen)
unsigned char * mask;
unsigned masklen;
const unsigned char * seed;
unsigned seedlen;
{
SHA1_CTX ctxt;
unsigned i = 0;
unsigned pos = 0;
unsigned char cnt[4];
unsigned char hout[SHA_DIGESTSIZE];
while(pos < masklen) {
cnt[0] = (i >> 24) & 0xFF;
cnt[1] = (i >> 16) & 0xFF;
cnt[2] = (i >> 8) & 0xFF;
cnt[3] = i & 0xFF;
SHA1Init(&ctxt);
SHA1Update(&ctxt, seed, seedlen);
SHA1Update(&ctxt, cnt, 4);
if(pos + SHA_DIGESTSIZE > masklen) {
SHA1Final(hout, &ctxt);
memcpy(mask + pos, hout, masklen - pos);
pos = masklen;
}
else {
SHA1Final(mask + pos, &ctxt);
pos += SHA_DIGESTSIZE;
}
++i;
}
memset(hout, 0, sizeof(hout));
memset((unsigned char *)&ctxt, 0, sizeof(ctxt));
}

View File

@@ -1,246 +0,0 @@
/*
* Copyright (c) 1997-2007 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Redistributions in source or binary form must retain an intact copy
* of this copyright notice.
*/
#ifndef T_PWD_H
#define T_PWD_H
#include <stdio.h>
#include "cstr.h"
#define MAXPARAMBITS 2048
#define MAXPARAMLEN ((MAXPARAMBITS + 7) / 8)
#define MAXB64PARAMLEN ((MAXPARAMBITS + 5) / 6 + 1)
#define MAXHEXPARAMLEN ((MAXPARAMBITS + 3) / 4 + 1)
#define MAXOCTPARAMLEN ((MAXPARAMBITS + 2) / 3 + 1)
#define MAXUSERLEN 32
#define MAXSALTLEN 32
#define MAXB64SALTLEN 44 /* 256 bits in b64 + null */
#define SALTLEN 10 /* Normally 80 bits */
#define RESPONSE_LEN 20 /* 160-bit proof hashes */
#define SESSION_KEY_LEN (2 * RESPONSE_LEN) /* 320-bit session key */
#define DEFAULT_PASSWD "/etc/tpasswd"
#define DEFAULT_CONF "/etc/tpasswd.conf"
struct t_num { /* Standard byte-oriented integer representation */
int len;
unsigned char * data;
};
struct t_preconf { /* Structure returned by t_getpreparam() */
char * mod_b64;
char * gen_b64;
char * comment;
struct t_num modulus;
struct t_num generator;
};
/*
* The built-in (known good) parameters access routines
*
* "t_getprecount" returns the number of precompiled parameter sets.
* "t_getpreparam" returns the indicated parameter set.
* Memory is statically allocated - callers need not perform any memory mgmt.
*/
_TYPE( int ) t_getprecount();
_TYPE( struct t_preconf * ) t_getpreparam P((int));
struct t_confent { /* One configuration file entry (index, N, g) */
int index;
struct t_num modulus;
struct t_num generator;
};
struct t_conf { /* An open configuration file */
FILE * instream;
char close_on_exit;
cstr * modbuf;
cstr * genbuf;
struct t_confent tcbuf;
};
/*
* The configuration file routines are designed along the lines of the
* "getpw" functions in the standard C library.
*
* "t_openconf" accepts a stdio stream and interprets it as a config file.
* "t_openconfbyname" accepts a filename and does the same thing.
* "t_closeconf" closes the config file.
* "t_getconfent" fetches the next sequential configuration entry.
* "t_getconfbyindex" fetches the configuration entry whose index
* matches the one supplied, or NULL if one can't be found.
* "t_getconflast" fetches the last configuration entry in the file.
* "t_makeconfent" generates a set of configuration entry parameters
* randomly.
* "t_newconfent" returns an empty configuration entry.
* "t_cmpconfent" compares two configuration entries a la strcmp.
* "t_checkconfent" verifies that a set of configuration parameters
* are suitable. N must be prime and should be a safe prime.
* "t_putconfent" writes a configuration entry to a stream.
*/
_TYPE( struct t_conf * ) t_openconf P((FILE *));
_TYPE( struct t_conf * ) t_openconfbyname P((const char *));
_TYPE( void ) t_closeconf P((struct t_conf *));
_TYPE( void ) t_rewindconf P((struct t_conf *));
_TYPE( struct t_confent * ) t_getconfent P((struct t_conf *));
_TYPE( struct t_confent * ) t_getconfbyindex P((struct t_conf *, int));
_TYPE( struct t_confent * ) t_getconflast P((struct t_conf *));
_TYPE( struct t_confent * ) t_makeconfent P((struct t_conf *, int));
_TYPE( struct t_confent * ) t_makeconfent_c P((struct t_conf *, int));
_TYPE( struct t_confent * ) t_newconfent P((struct t_conf *));
_TYPE( int ) t_cmpconfent P((const struct t_confent *, const struct t_confent *));
_TYPE( int ) t_checkconfent P((const struct t_confent *));
_TYPE( void ) t_putconfent P((const struct t_confent *, FILE *));
/* libc-style system conf file access */
_TYPE( struct t_confent *) gettcent();
_TYPE( struct t_confent *) gettcid P((int));
_TYPE( void ) settcent();
_TYPE( void ) endtcent();
#ifdef ENABLE_NSW
extern struct t_confent * _gettcent();
extern struct t_confent * _gettcid P((int));
extern void _settcent();
extern void _endtcent();
#endif
/* A hack to support '+'-style entries in the passwd file */
typedef enum fstate {
FILE_ONLY, /* Ordinary file, don't consult NIS ever */
FILE_NIS, /* Currently accessing file, use NIS if encountered */
IN_NIS, /* Currently in a '+' entry; use NIS for getXXent */
} FILE_STATE;
struct t_pwent { /* A single password file entry */
char * name;
struct t_num password;
struct t_num salt;
int index;
};
struct t_pw { /* An open password file */
FILE * instream;
char close_on_exit;
FILE_STATE state;
char userbuf[MAXUSERLEN];
cstr * pwbuf;
unsigned char saltbuf[SALTLEN];
struct t_pwent pebuf;
};
/*
* The password manipulation routines are patterned after the getpw*
* standard C library function calls.
*
* "t_openpw" reads a stream as if it were a password file.
* "t_openpwbyname" opens the named file as a password file.
* "t_closepw" closes an open password file.
* "t_rewindpw" starts the internal file pointer from the beginning
* of the password file.
* "t_getpwent" retrieves the next sequential password entry.
* "t_getpwbyname" looks up the password entry corresponding to the
* specified user.
* "t_makepwent" constructs a password entry from a username, password,
* numeric salt, and configuration entry.
* "t_putpwent" writes a password entry to a stream.
*/
_TYPE( struct t_pw * ) t_newpw();
_TYPE( struct t_pw * ) t_openpw P((FILE *));
_TYPE( struct t_pw * ) t_openpwbyname P((const char *));
_TYPE( void ) t_closepw P((struct t_pw *));
_TYPE( void ) t_rewindpw P((struct t_pw *));
_TYPE( struct t_pwent * ) t_getpwent P((struct t_pw *));
_TYPE( struct t_pwent * ) t_getpwbyname P((struct t_pw *, const char *));
_TYPE( struct t_pwent * ) t_makepwent P((struct t_pw *, const char *,
const char *, const struct t_num *,
const struct t_confent *));
_TYPE( void ) t_putpwent P((const struct t_pwent *, FILE *));
struct t_passwd {
struct t_pwent tp;
struct t_confent tc;
};
/* libc-style system password file access */
_TYPE( struct t_passwd * ) gettpent();
_TYPE( struct t_passwd * ) gettpnam P((const char *));
_TYPE( void ) settpent();
_TYPE( void ) endtpent();
#ifdef ENABLE_NSW
extern struct t_passwd * _gettpent();
extern struct t_passwd * _gettpnam P((const char *));
extern void _settpent();
extern void _endtpent();
#endif
/*
* Utility functions
*
* "t_verifypw" accepts a username and password, and checks against the
* system password file to see if the password for that user is correct.
* Returns > 0 if it is correct, 0 if not, and -1 if some error occurred
* (i.e. the user doesn't exist on the system). This is intended ONLY
* for local authentication; for remote authentication, look at the
* t_client and t_server source. (That's the whole point of SRP!)
* "t_changepw" modifies the specified file, substituting the given password
* entry for the one already in the file. If no matching entry is found,
* the new entry is simply appended to the file.
* "t_deletepw" removes the specified user from the specified file.
*/
_TYPE( int ) t_verifypw P((const char *, const char *));
_TYPE( int ) t_changepw P((const char *, const struct t_pwent *));
_TYPE( int ) t_deletepw P((const char *, const char *));
/* Conversion utilities */
/*
* All these calls accept output as the first parameter. In the case of
* t_tohex and t_tob64, the last argument is the length of the byte-string
* input.
*/
_TYPE( char * ) t_tohex P((char *, const char *, unsigned));
_TYPE( int ) t_fromhex P((char *, const char *));
_TYPE( char * ) t_tob64 P((char *, const char *, unsigned));
_TYPE( int ) t_fromb64 P((char *, const char *));
/* These functions put their output in a cstr object */
_TYPE( char * ) t_tohexcstr P((cstr *, const char *, unsigned));
_TYPE( int ) t_cstrfromhex P((cstr *, const char *));
_TYPE( char * ) t_tob64cstr P((cstr *, const char *, unsigned));
_TYPE( int ) t_cstrfromb64 P((cstr *, const char *));
/* Miscellaneous utilities (moved to t_defines.h) */
#endif

View File

@@ -1,276 +0,0 @@
#include "t_defines.h"
#include "t_sha.h"
#ifdef CRYPTOLIB_SHA
/* A wrapper around CryptoLib's shsFinal that delivers output in octets */
void
shsFinalBytes(unsigned char digest[20], SHS_CTX* context)
{
int i;
unsigned long r;
unsigned char *p = digest;
shsFinal(context);
for(i = 0; i < 5; ++i) {
r = context->h[i];
*p++ = (unsigned char)((r >> 24) & 0xff);
*p++ = (unsigned char)((r >> 16) & 0xff);
*p++ = (unsigned char)((r >> 8) & 0xff);
*p++ = (unsigned char)(r & 0xff);
}
}
#elif defined(GCRYPT_SHA)
/* Wrappers for gcrypt's md interface */
void
SHA1Init_gcry(SHA1_CTX * ctx)
{
gcry_md_open(ctx, GCRY_MD_SHA1, 0);
}
void
SHA1Update_gcry(SHA1_CTX * ctx, const void *data, unsigned int len)
{
gcry_md_write(*ctx, data, len);
}
void
SHA1Final_gcry(unsigned char digest[20], SHA1_CTX * ctx)
{
memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA1), 20);
gcry_md_close(*ctx);
}
void
SHA512Init_gcry(SHA512_CTX * ctx)
{
gcry_md_open(ctx, GCRY_MD_SHA512, 0);
}
void
SHA512Update_gcry(SHA512_CTX * ctx, const void *data, unsigned int len)
{
gcry_md_write(*ctx, data, len);
}
void
SHA512Final_gcry(unsigned char digest[64], SHA512_CTX * ctx)
{
memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA512), 64);
gcry_md_close(*ctx);
}
#elif defined(MBEDTLS_SHA)
/* Wrappers for mbedtls's md interface */
void
SHA1Init_mbed(SHA1_CTX * ctx)
{
mbedtls_md_init(ctx);
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 0);
mbedtls_md_starts(ctx);
}
void
SHA1Update_mbed(SHA1_CTX * ctx, const void *data, unsigned int len)
{
mbedtls_md_update(ctx, data, len);
}
void
SHA1Final_mbed(unsigned char digest[20], SHA1_CTX * ctx)
{
mbedtls_md_finish(ctx, digest);
mbedtls_md_free(ctx);
}
void
SHA512Init_mbed(SHA512_CTX * ctx)
{
mbedtls_md_init(ctx);
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), 0);
mbedtls_md_starts(ctx);
}
void
SHA512Update_mbed(SHA512_CTX * ctx, const void *data, unsigned int len)
{
mbedtls_md_update(ctx, data, len);
}
void
SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx)
{
mbedtls_md_finish(ctx, digest);
mbedtls_md_free(ctx);
}
#elif !defined(OPENSSL_SHA) && !defined(TOMCRYPT_SHA)
/* Use the free SHA1 if the library doesn't have it */
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#include <stdio.h>
#include <string.h>
static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#ifndef WORDS_BIGENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
static void SHA1Transform(uint32 state[5], const unsigned char buffer[64])
{
uint32 a, b, c, d, e;
typedef union {
unsigned char c[64];
uint32 l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
uint32 i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}
#endif /* OPENSSL */

View File

@@ -1,125 +0,0 @@
#ifndef T_SHA_H
#define T_SHA_H
#if !defined(P)
#ifdef __STDC__
#define P(x) x
#else
#define P(x) ()
#endif
#endif
#define SHA_DIGESTSIZE 20
#ifdef OPENSSL
#define OPENSSL_SHA 1
#endif
#ifdef TOMCRYPT
# include <tomcrypt.h>
# ifdef SHA1
# define TOMCRYPT_SHA 1
# endif
#endif
#ifdef CRYPTOLIB
/* The SHA (shs) implementation in CryptoLib 1.x breaks when Update
* is called multiple times, so we still use our own code.
* Uncomment below if you think your copy of CryptoLib is fixed. */
/*#define CRYPTOLIB_SHA 1*/
#endif
#ifdef GCRYPT
# define GCRYPT_SHA 1
#endif
#ifdef MBEDTLS
# define MBEDTLS_SHA 1
#endif
#ifdef OPENSSL_SHA
#include <openssl/sha.h>
typedef SHA_CTX SHA1_CTX;
#define SHA1Init SHA1_Init
#define SHA1Update SHA1_Update
#define SHA1Final SHA1_Final
#define SHA512Init SHA512_Init
#define SHA512Update SHA512_Update
#define SHA512Final SHA512_Final
#elif defined(TOMCRYPT_SHA)
/* mycrypt.h already included above */
typedef hash_state SHA1_CTX;
#define SHA1Init sha1_init
#define SHA1Update sha1_process
#define SHA1Final(D,C) sha1_done(C,D)
#elif defined(GCRYPT_SHA)
#include "gcrypt.h"
typedef gcry_md_hd_t SHA1_CTX;
#define SHA1Init SHA1Init_gcry
#define SHA1Update SHA1Update_gcry
#define SHA1Final SHA1Final_gcry
typedef gcry_md_hd_t SHA512_CTX;
#define SHA512Init SHA512Init_gcry
#define SHA512Update SHA512Update_gcry
#define SHA512Final SHA512Final_gcry
void SHA1Init_gcry(SHA1_CTX * ctx);
void SHA1Update_gcry(SHA1_CTX * ctx, const void *data, unsigned int len);
void SHA1Final_gcry(unsigned char digest[20], SHA1_CTX * ctx);
void SHA512Init_gcry(SHA512_CTX * ctx);
void SHA512Update_gcry(SHA512_CTX * ctx, const void *data, unsigned int len);
void SHA512Final_gcry(unsigned char digest[64], SHA512_CTX * ctx);
#elif defined(MBEDTLS_SHA)
#include <mbedtls/md.h>
typedef mbedtls_md_context_t SHA1_CTX;
#define SHA1Init SHA1Init_mbed
#define SHA1Update SHA1Update_mbed
#define SHA1Final SHA1Final_mbed
typedef mbedtls_md_context_t SHA512_CTX;
#define SHA512Init SHA512Init_mbed
#define SHA512Update SHA512Update_mbed
#define SHA512Final SHA512Final_mbed
void SHA1Init_mbed(SHA1_CTX * ctx);
void SHA1Update_mbed(SHA1_CTX * ctx, const void *data, unsigned int len);
void SHA1Final_mbed(unsigned char digest[20], SHA1_CTX * ctx);
void SHA512Init_mbed(SHA512_CTX * ctx);
void SHA512Update_mbed(SHA512_CTX * ctx, const void *data, unsigned int len);
void SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx);
#elif defined(CRYPTOLIB_SHA)
#include "libcrypt.h"
typedef SHS_CTX SHA1_CTX;
#define SHA1Init shsInit
#define SHA1Update shsUpdate
#define SHA1Final shsFinalBytes
void shsFinalBytes P((unsigned char digest[20], SHS_CTX* context));
#else
typedef unsigned int uint32;
typedef struct {
uint32 state[5];
uint32 count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Init P((SHA1_CTX* context));
void SHA1Update P((SHA1_CTX* context, const unsigned char* data, unsigned int len));
void SHA1Final P((unsigned char digest[20], SHA1_CTX* context));
#endif /* !OPENSSL && !CRYPTOLIB */
#endif /* T_SHA_H */

View File

@@ -1,242 +0,0 @@
/*
* Physically random numbers (very nearly uniform)
* D. P. Mitchell
* Modified by Matt Blaze 7/95
*/
/*
* The authors of this software are Don Mitchell and Matt Blaze.
* Copyright (c) 1995 by AT&T.
* Permission to use, copy, and modify this software without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software and in all copies of the supporting
* documentation for such software.
*
* This software may be subject to United States export controls.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/
/*
* WARNING: depending on the particular platform, raw_truerand()
* output may be biased or correlated. In general, you can expect
* about 16 bits of "pseudo-entropy" out of each 32 bit word returned
* by truerand(), but it may not be uniformly diffused. You should
* raw_therefore run the output through some post-whitening function
* (like MD5 or DES or whatever) before using it to generate key
* material. (RSAREF's random package does this for you when you feed
* raw_truerand() bits to the seed input function.)
*
* The application interface, for 8, 16, and 32 bit properly "whitened"
* random numbers, can be found in trand8(), trand16(), and trand32().
* Use those instead of calling raw_truerand() directly.
*
* The basic idea here is that between clock "skew" and various
* hard-to-predict OS event arrivals, counting a tight loop will yield
* a little (maybe a third of a bit or so) of "good" randomness per
* interval clock tick. This seems to work well even on unloaded
* machines. If there is a human operator at the machine, you should
* augment truerand with other measure, like keyboard event timing.
* On server machines (e.g., when you need to generate a
* Diffie-Hellman secret) truerand alone may be good enough.
*
* Test these assumptions on your own platform before fielding a
* system based on this software or these techniques.
*
* This software seems to work well (at 10 or so bits per
* raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
* P100 under BSDI 2.0. You're on your own elsewhere.
*
*/
#include "t_defines.h"
#ifdef WIN32
# ifdef CRYPTOLIB
/* Cryptolib contains its own truerand() on both UNIX and Windows. */
/* Only use cryptolib's truerand under Windows */
# include "libcrypt.h"
unsigned long
raw_truerand()
{
return truerand();
}
# else /* !CRYPTOLIB && WIN32 */
#include <windows.h>
#include <wtypes.h>
#include <winbase.h>
#include <windef.h>
#include <winnt.h>
#include <winuser.h>
#include <process.h>
volatile unsigned long count, ocount, randbuf;
volatile int dontstop;
char outbuf[1024], *bufp;
static void counter() {
while (dontstop)
count++;
_endthread();
}
static unsigned long roulette() {
unsigned long thread;
count = 0;
dontstop= 1;
while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0)
;
Sleep(16);
dontstop = 0;
Sleep(1);
count ^= (count>>3) ^ (count>>6) ^ (ocount);
count &= 0x7;
ocount = count;
randbuf = (randbuf<<3) ^ count;
return randbuf;
}
unsigned long
raw_truerand() {
roulette();
roulette();
roulette();
roulette();
roulette();
roulette();
roulette();
roulette();
roulette();
roulette();
return roulette();
}
# endif /* CRYPTOLIB */
#else /* !WIN32 */
#include <signal.h>
#include <setjmp.h>
#include <sys/time.h>
#include <math.h>
#include <stdio.h>
#ifdef OLD_TRUERAND
static jmp_buf env;
#endif
static unsigned volatile count
#ifndef OLD_TRUERAND
, done = 0
#endif
;
static unsigned ocount;
static unsigned buffer;
static void
tick()
{
struct itimerval it, oit;
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 16665;
if (setitimer(ITIMER_REAL, &it, &oit) < 0)
perror("tick");
}
static void
interrupt()
{
if (count) {
#ifdef OLD_TRUERAND
longjmp(env, 1);
#else
++done;
return;
#endif
}
(void) signal(SIGALRM, interrupt);
tick();
}
static unsigned long
roulette()
{
#ifdef OLD_TRUERAND
if (setjmp(env)) {
count ^= (count>>3) ^ (count>>6) ^ ocount;
count &= 0x7;
ocount=count;
buffer = (buffer<<3) ^ count;
return buffer;
}
#else
done = 0;
#endif
(void) signal(SIGALRM, interrupt);
count = 0;
tick();
#ifdef OLD_TRUERAND
for (;;)
#else
while(done == 0)
#endif
count++; /* about 1 MHz on VAX 11/780 */
#ifndef OLD_TRUERAND
count ^= (count>>3) ^ (count>>6) ^ ocount;
count &= 0x7;
ocount=count;
buffer = (buffer<<3) ^ count;
return buffer;
#endif
}
unsigned long
raw_truerand()
{
count=0;
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
(void) roulette();
return roulette();
}
int
raw_n_truerand(n)
int n;
{
int slop, v;
slop = 0x7FFFFFFF % n;
do {
v = raw_truerand() >> 1;
} while (v <= slop);
return v % n;
}
#endif /* !CRYPTOLIB || !WIN32 */

View File

@@ -1,21 +0,0 @@
Bastien Nocera
Bryan Forbes
Christophe Fergeau
Geoff Paul
Ingmar Vanhassel
John Maguire
Jonathan Beck
Joshua Hill
Julien Lavergne
Martin Aumueller
Martin Szulecki
Marty Rosenberg
Matt Colyer
Nikias Bassen
Patrick Walton
Paul Sladen
Peter Hoepfner
Petr Uzel
Todd Zullinger
Zach C
Zoltan Balaton

View File

@@ -1,340 +0,0 @@
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.

View File

@@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 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.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either
version 2.1 of the License, or (at your option) any later version.
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; 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.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -1,21 +0,0 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = 3rd_party common src include $(CYTHON_SUB) tools docs
EXTRA_DIST = \
docs \
README.md \
git-version-gen
dist-hook:
echo $(VERSION) > $(distdir)/.tarball-version
docs/html: $(top_builddir)/doxygen.cfg $(top_srcdir)/src/*.c $(top_srcdir)/src/*.h $(top_srcdir)/include/libimobiledevice/*.h
rm -rf docs/html
doxygen doxygen.cfg
docs: doxygen.cfg docs/html
indent:
indent -kr -ut -ts4 -l120 src/*.c src/*.h

View File

@@ -1,571 +0,0 @@
Version 1.3.0
~~~~~~~~~~~~~
* Development release "Let's get the party started."
* Changes:
- Fix Python 3 support
- Add more lockdown error codes
- Add new lockdownd_pair_with_options() function
- Fix GnuTLS support with iOS 10
- Make sure sockets only listen locally due to security reasons
- Plug various memory leaks
- Fix SSL version negotiation for newer versions of OpenSSL
- Optimize lockdown pair record handling
- Return proper error code when a lockdown pair record is missing
- Fix building with MingGW
- Store application information in Info.plist using idevicebackup2
- Fix application backup handling to allow the device to restore applications
that were installed using idevicebackup2
- Make idevicebackup2 reboot after restore the default to allow the device to
migrate data correctly and thus improve the restored device data state
- Improve console frontend information output in idevicebackup2
- Extend ideviceprovision tool to allow retrieving and removing all
provisioning profiles
- Fix parsing large provisioning profile using ideviceprovision
- Fix receiving large property lists in property list service
- Propagate lower level errors to callers instead of returning
IDEVICE_E_UNKNOWN_ERROR
- API: Add IDEVICE_DEVICE_PAIRED event type
- Detect screenshot format to support png, tiff and dat formats using
idevicescreenshot tool
- API: Add mobileactivation service implementation
- Wait for passcode entry if required using idevicesyslog
- Add HDMI option to diagnostics command for idevicediagnostics
- Fix IORegistry command for iOS 11+ devices in idevicediagnostics
- Remove 40-digit character limit for UDID in tools to support newer devices
- Fix broken validate command in idevicepair with iOS 11+
- Fix OpenSSL version checks for configure target when using LibreSSL
- Migrate latest improved common code from libusbmuxd
- Convert README file to markdown format
- Fix idevicecrashreport tool to work with iOS 13+
- Fix various errors in SSL communication logic
- API: Add preboard service implementation
- Output hint to user to enter passcode when changing password using
idevicebackup2
- Cython: Fix and improve debugserver and diagnostics service bindings
- API: Add WiFi device support via new idevice_new_with_options() function
- API: Add idevice_get_device_list_extended() to also list network devices
- API: Add lockdown_strerror() helper to get error representation as string
- Add network device support to idevicesyslog and ideviceinfo tools
- Make debug output consistently output to stderr
- Add new idevicesetlocation tool (requires mounted developer image)
- Add option to exit if device disconnects in idevicesyslog
- API: Add syslog_relay_start_capture_raw() for raw syslog capture
- Add color output and process filter support to idevicesyslog
- API: Add companion_proxy service implementation
- Bump dependency to libusbmuxd 2.0.2
- Bump dependency to libplist 2.2.0
- Improve error handling and reporting in library and tools
- Fix various memory leaks in library and tools
- Add "--network" and "--version" options to all tools
- Fix socket_connect_addr() not connecting to network devices using IPv6
in some cases.
- Improve IPv6 "scope id" detection to fix connecting to network devices with
link-local adresses.
- Update man pages
- Fix various inconsistent declarations in public headers
- Allow OpenSSL >= 1.1.0 to use older/disallowed TLS versions fixing issues
where pairing records were getting removed repeatingly
- Fixed memory leaks
- Cython: Rewrite version detection logic in configure.ac
- Rename "--enable-debug-code" configure option to "--enable-debug"
- Improve README.md with project description, installation, contributing and
usage sections
- Rename library and all related files by adding an API version resulting
in "libimobiledevice-1.0"
- Bump soname version
* API is UNSTABLE
Version 1.2.0
~~~~~~~~~~~~~
* Stable release "It took you so long baby!"
* Changes:
- Require autoconf 2.64 or later
- Remove dev tools, will return either as proper tools or website examples
- Refactor installation proxy service implementation and normalize code
- API: Added instproxy_lookup() to efficiently lookup app information
- API: Added instproxy_check_capabilities_match() to check device capabilities
- API: Added various instproxy command and status plist getters
- API: Make debugserver_client_set_ack_mode() public
- Fix handling of clients reconnecting in idevicedebugserverproxy which
previously didn't work properly
- Flush stdout for every line in idevicesyslog
- Fix shutdown of idevicedebugserverproxy tool which could hang
- Notify user when erroneously using idevicebackup with iOS 4 or later
- Enable build of idevicecrashreport on WIN32
- Fix thread handle leaks on WIN32 adding thread_new and thread_free
- cython: Add receive/receive_timeout methods for iDeviceConnection to
receive raw data from a connection
- cython: Add new FILE_RELAY_E_PERMISSION_DENIED(-6) error
- API: Refactor lockdown service internal error checking and add a bunch of
new native errors
- Convert int16_t macro error types into enum within common module, too
- Add new "idevicenotificationproxy" tool to post or observe notifications
- Fix overlong blocking in np_client_free()
- Improve maintainability and Requires of pkg-config file
- API: Add new LOCKDOWN_E_SERVICE_LIMIT error to detect service limit states
- API: Remove const argv requirement for debugserver_command_new
- cython: Add get_path_for_bundle_identifier() method to
InstallationProxyClient
- cython: Add DebugServerClient class to communicate with debugserver
- Comply to strict function prototypes by using (void) instead of just ()
- Fix notification proxy shutdown process which was incorrectly implemented
- Fix linking problems on OS X
- Fix missing debug output which broke with the last release
- Unify and improve various debug messages
- Fix re-pairing if pairing with existing pair record failed initially
- Skip printing long plist (16kb+) files to prevent excessive debug output
- Move a few common helpers from backup tools to common utility helper code
- Remove incorrect flags from afc_file_open() documentation
- Fix various memory leaks
Version 1.1.7
~~~~~~~~~~~~~
* Development release "Cleaning up the yard."
* Changes:
- Fix broken app args, environment handling and memory leaks in idevicedebug
- Make all tools print an error if lockdown connection fails
- Convert int16_t macro error types into enum for better type-checking and
for various debugging benefits
- Avoid exporting non-public symbols for better ABI stability
- Fix failing backup process for devices having a passcode set and entering
lock state during the process in idevicebackup2
- API: Added lockdownd_start_service_with_escrow_bag()
- API: Added afc_remove_path_and_contents() for recursive deletion
- Fix last memory leak with OpenSSL through proper library deinitialization
- Add new idevicedebug tool to interact with debugserver on a device
- API: Add debugserver service implementation
- Handle new PermissionDenied error of file_relay due new security in iOS 8+
- Fix retry loop problem when device requests 0 files in idevicebackup2
- Add trust dialog related error codes to Cython bindings
- Fix various memory leaks in AFC implementation
- Fix disk image upload with latest iOS 8 in ideviceimagemounter
- Add new "dump" command to print information about a provisioning profile in
ideviceprovision
- Refactor plist print helper code and move it into common module for better
reuse accross the tools
- Do not crash if retrieving the system buid fails
- API: Make generic "propery_list_service_client" public
- Moved doc comments from private to public headers
- Fix possible segfault when using lockdownd_get_value() due to always
returning success
- Do not read files entirely into memory during restore in idevicebackup
- Plug a few memory leaks and fix invalid password check in idevicebackup2
- Add support for file sizes > 4GB on Win32 in idevicebackup2
- Fix declaration for DllMain on Win32
- Silence various compiler warnings
- Fix assert within pairing logic
* API is UNSTABLE
Version 1.1.6
~~~~~~~~~~~~~
* Development release "Way too overdue."
* Changes:
- Remove segmentation code from afc_file_read() to provide raw interface and
more control to API consumer I/O logic
- Implement global thread safe library initialization, especially to control
SSL backend lifecycle
- Major refactoring of pair record code and logic to use new usbmuxd pair
record management interface
- Replace user level with system wide pair record file handling
- Bump dependency to libplist 1.11 and remove use of "plist_dict_insert_item"
- Bump dependency to libusbmuxd 1.0.9
- Finish pair record and trust dialog handling for iOS 7+
- Improve AFC write performance and memory usage
- Add support for custom output filename to idevicescreenshot
- Fix detection and compilation for Python 3.x
- API: Added file_relay_request_sources_timeout()
- Fix broken HouseArrestClient class in cython bindings
- Add new idevicecrashreport tool to retrieve crash reports and logs from a
device
- Prevent "Failed to restart/shutdown device" messages in idevicediagnostics
- Link against ws2_32.dll on Win32
- Add support for iOS 7+ disk image mounting to ideviceimagemounter
- Add new idevicename tool to get or set the device name
- Allow unbacking of encrypted backups with a given password to idevicebackup2
- Remove sending "Goodbye" request on lockdown
- Add support for newer PLIST_REAL based time type to idevicedate
- Add note about setting time not working on iOS 6+ to idevicedate
- Handle partial SSL reads correctly now to prevent random crashes
- Fix duplicated output in ideviceinfo output
- Remove a bunch of dead code
- Fix deprecated OpenSSL "RSA_generate_key" with "RSA_generate_key_ex" which
is available since OpenSSL 0.9.8 (July 2005)
- Improve debug messages
- Enforce "-fsigned-char" to fix issues on embedded platforms
- Fix compilation with Clang/LLVM
- Avoid versioning for shared library on Win32
- Add experimental support for controlling cloud backup mode to idevicebackup2
- Save EscrowBag when starting service for automatic unlocking in pair record
- Remove pairing logic which is obsoleted by usbmuxd's preflight handler
- Fix shutdown of SSL connection to be correct and no longer generate errors
on device
- Add support for GnuTLS 3.x and fix broken GnuTLS backend
- Add extensions to generated certificates to match native ones
- Add "systembuid" command to idevicepair
- Allow starting service without the need for a running SSL session
- Refactor more code into common module
- Add option to filerelaytest to specify a source to request
- Fix support for partial messages in webinspector implementation
- Implement support for encrypted backups in idevicebackup2
- API: Export SSL control functions for idevice_connection_t
- API: Make generic service client public to allow external service
implementations
- Implement *_start_service() helper for easier creation of service clients
- Add public *_SERVICE_NAME defines for each service
- Fix a great bunch of memory leaks after intensive valgrind session
- Security: Fix insecure use of the /tmp directory (CVE-2013-2142)
- A bunch of memory leak fixes
- Python: Various fixes and support for "with" statement for AfcFile class
- Python: Add Afc2Client class to allow jailbroken filesystem access
- Fix linking issue with newer libtool as reported for Ubuntu
- Fix stuck thread in idevicesyslog which broke quit from within the tool
- Add syslog_relay service implementation and use it in idevicesyslog
- API: Add instproxy_client_get_path_for_bundle_identifier() helper
- API: Add afc_dictionary_free() helper
- Move thread, socket, debug and userpref code to "common" source directory
in order to improve code reuse
- Fix broken byte order detection in configure.ac which could lead to broken
AFC protocol communication on platforms without endian.h (Raspberry PI)
* API is UNSTABLE
Version 1.1.5
~~~~~~~~~~~~~
* Development release
* Changes:
- Implement automatic reconnecting in idevicesyslog
- Refactor all services to use new base service
- Add new generic service_client_factory_start_service() helper
- Implement a base service that all services inherit from
- API: Refactor use of "port numbers" into a "service descriptor" which is
a needed change as all services must now transparently support SSL.
Fortunately, only minor changes are needed to migrate your code properly.
- Add experimental ideviceheartbeat to allow service checkin over the network
- Add heartbeat service implementation to keep alive network connections
- Add webinspector service implementation for WebKit remote debugging
- Fix idevicebackup2 failing due to integer overflow in free disk space
calculation on 32 bit architectures and large disk capacities
- Add support for encrypted and password protected backups to idevicebackup2
- Fix major "too long filename received" bug in idevicebackup2
- Various fixes for proper and tested WIN32 support including MinGW building
- Fix various crashers and improve quality of idevicebackup2 tool
- Add endianness helpers for systems lacking support
- Fix idevicedate to work on iOS 6+
- Add idevicediagnostics tool
- Add diagnostics_relay service implementation
- Add idevicedebugserverproxy tool for remote lldb debugging
- Add ideviceprovision tool
- Add misagent service implementation to manage provisioning profiles
- Fix crash if $HOME is empty or not defined
- Fix non-ASCII characters being stripped when using plist communication
- Improve compile support for cython and check it at configure time
- Bump cython requirement to 0.17.0+
- Fix compilation of cython bindings
- Python bindings now cover all C APIs
- Fix iOS 6 compatibility for mobilesync, mobilebackup, mobilebackup2 and
screenshotr by bumping device link protocol version number
- Do not strip non_ASCII characters from XML plists
- Fix possible crash when using OpenSSL
* API is UNSTABLE
Version 1.1.4
~~~~~~~~~~~~~
* Development release
* Changes:
- Fix a bug in idevicesyslog causing the connection to close after timeout
- Bump soname revision
* API is UNSTABLE
Version 1.1.3
~~~~~~~~~~~~~
* Development release
* Changes:
- Bump libusbmuxd dependency to 1.0.8
- Fix reading from syslog_relay and remove null characters
- Relicense ideviceimagemounter and idevicescreenshot to LGPL
- Fix a crash when using restored_client_free()
- API: Add sbservices_get_interface_orientation()
- Update man pages and code comments for documentation
- Minor cleanup
* API is UNSTABLE
Version 1.1.2
~~~~~~~~~~~~~
* Development release
* Changes:
- Add Python bindings generated by Cython
- Bump libplist requirement to latest 1.8
- Add support for OpenSSL with fallback to GNUTLS
- Improvements and various fixes for Win32 and OS X build
- Remove glib dependency
- Improve restored implementation
- Fix various memory leaks
- Fix support for iOS 5 and later
* SWIG Python Bindings are removed
* API is UNSTABLE
Version 1.1.1
~~~~~~~~~~~~~
* Development release
* Changes:
- Add new idevicebackup2 tool for full backup and restore support on iOS 4+
- Add a workaround for a bug in iOS 4.3 affecting lockdown_get_value() which
most prominently affected libgpod, gvfs, ideviceinfo and some other tools
- Read ProxyDeath message to preventing obsolete messages in device syslog
- Rework SWIG detection and includes
- Add new idevicedate tool to get or set the clock on iDevices
- API: Add mobilesync_clear_all_records_on_device()
- API: Change device_link_service_disconnect() to accept a message
- Add manpages for ideviceenterrecovery, idevicepair, idevicebackup2 and
idevicedate
- Add missing libgen.h include to silence compiler warnings
- Fix a segfault that might occour if locally stored certs could not be read
- Fix various memory leaks
- Update documentation
* Python Bindings will get refactored completely
* API is UNSTABLE
Version 1.1.0
~~~~~~~~~~~~~
* Development release
* Changes:
- Implement restoring backups using idevicebackup
- Allow connecting without pairing using "ideviceinfo -s"
- Add ideviceenterrecovery tool
- Add mobilesync service implementation
- Add restored service implementation for restore mode
- Add home_arrest service implementation for document sharing
- Add API afc_client_new_from_connection()
- Support to fetch wallpaper in sbservices
- Support for formatVersion 2 of iOS 4+ in sbservices
- Add new lockdownd domains to ideviceinfo
- Give the device time to prepare backup data to prevent abort
- Improve idevicebackup output
- notification_proxy fixes and new notification type
- Silence some 64bit compiler warnings
- Fix various memory leaks
- Update documentation
* Python Bindings will get refactored completely
* API is UNSTABLE
Version 1.0.7
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Fix SWIG 2.x detection
- Fix support for iOS 5 and later
- Flush output of idevicesyslog immediately
- Replace deprecated GNUTLS functions properly
- Fix segfaults in library and some tools
- Fix memory leaks
- Build fixes
Version 1.0.6
~~~~~~~~~~~~~
* Quick follow up release
* Changes:
- Add ideviceenterrecovery which was missing in last release by accident
Version 1.0.5
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Add a workaround for a bug in iOS 4.3 affecting lockdown_get_value() which
most prominently affected libgpod, gvfs, ideviceinfo and some other tools
- Read ProxyDeath message to preventing obsolete messages in device syslog
- Rework SWIG detection and includes
- Add manpages for ideviceenterrecovery and idevicepair
- Add missing libgen.h include to silence compiler warnings
Version 1.0.4
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Fix a possible crash in lockdownd_client_new_with_handshake()
- Do not not check for Swig/Python if --without-swig is set
- Fail with an error message if libgcrypt is not found
- Pass host certificate with GNUTLS correctly
- Fix connecting to iOS 4.2.1+ devices
Version 1.0.3
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Terminate idevicesyslog on receive errors (like device unplug)
- Bugfixes for idevicebackup tool
- Hopefully the last fixes for big endian machines
- Build fixes for FreeBSD Python support
- Fix build on Mac OS X
Version 1.0.2
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Backport new idevicepair tool to manage pairings
- Fix a bug causing bad backup data
- Silence 64bit compiler warnings
- Plug some memory leaks
Version 1.0.1
~~~~~~~~~~~~~
* Maintenance release of stable series
* Changes:
- Cleanup includes of files
- Use glib instead of netinet for endianess
- Fix installation_proxy not adding client options correctly
- idevicebackup: better handle broken or missing plist files
- Fix some memory leaks in pairing/handshake process
- Fix label not being used in lockdownd_client_new()
- Update AUTHORS, README and installation instructions
Version 1.0.0
~~~~~~~~~~~~~
* Changes:
- Update and fix documentation for full coverage
- Add man pages for tools
- Extend mobilebackup interface
- Add user data argument to notification callback function
- Fix broken Python bindings
- Add Python bindings for notification proxy interface
- Add screenshotr interface and tool
- Add mobile_image_mounter interface and tool
- Remove HAL fdi rules
Version 0.9.7 (RC1)
~~~~~~~~~~~~~~~~~~~
* Project is now called libimobiledevice due to legal reasons
* Changes:
- Project renamed to libimobiledevice
- Add soname versioning for future releases
- Fix regression causing never paired devices to not work by adding
auto-pairing for devices in lockdownd_client_new_with_handshake
- Add file_relay service implementation and dev test tool
- Minor device link service fixes
- New idevicebackup tool with support for full and incremental backups
- Add mobilebackup service implementation
Version 0.9.6
~~~~~~~~~~~~~
* Changes:
- Minor public API changes to prepare for 1.0 release:
* lockdownd_client_new -> lockdownd_client_new_with_handshake
* fooservice_recv -> fooservice_receive
* iphone_device_send/_recv -> iphone_connection_send/_receive
- Rename some code for consistency
- Refactor pairing to allow custom pair records
- Move SSL handling out of lockdownd code
- Refactor lockdown session handling code
- Remove debug mask support
- No longer do a full lockdown handshake on client_new
- Refactor debug code to be consistent and easier to use
- Run validate_pair by default during lockdown handshake
- Allow retrieving the type for lockdown query_type request
- Add new property_list_service and device_link_service abstractions
- Detect pairing failure due to having a password set on the device
- Implement lockdown phone activation and deactivation
- Fix iphoneinfo not printing values in key/value mode
- Implement lockdownd_unpair() request
- Add more notification ids and lockdown domains
- Implement label support for lockdown requests
- Add new installation_proxy interface
- Add new sbservices interface
- Implement lockdownd_validate_pair() request
- Add endian safety to AFC
- Make lockdown sessions without SSL work
- Fix linking on Mandriva Linux
- Minor bugfixes and documentation updates
Version 0.9.5
~~~~~~~~~~~~~
* Changes:
- Updated to the latest libplist 0.16 API
- Fixed various minor leaks and issues
- Updated Python bindings and module name
Version 0.9.4
~~~~~~~~~~~~~
* Changes:
- Update to libplist 0.15 API rework
- Update Python bindings
- Bufixes around usbmuxd daemon usage
- Use automake 1.11 silent rules if available
- Various bugfixes
Version 0.9.3
~~~~~~~~~~~~~
* Changes:
- Bump libplist requirement to 0.13 and remove deprecated code
Version 0.9.2
~~~~~~~~~~~~~
* Changes:
- Migrate to use the new usbmuxd daemon
- Refactor whole API
- Add iPhone 3GS support
- Add hard/symlink support for AFC
- New iphone_id tool to list connected devices and get the device
name
- iphoneinfo now allows plist/xml output and queries by
domain/key
- Fix a lot of bugs/crashes, compiler warnings and comments
Version 0.9.1
~~~~~~~~~~~~~
* Changes:
- Fix make distcheck
- Bump libplist requirement to 0.12 and remove deprecated code
- A bunch of autotools fixes
Version 0.9.0
~~~~~~~~~~~~~
* Changes:
- Fix pkg-config dependancies
- Fix Python binding generation
- AFC cleanup and improved error handling
- Add support for the notification proxy service
- Add tools to show device information and relay syslog
- More robust pairing implementation
- Remove libiphone-initconf, SSL implementation handles it at
runtime now
- Fix receive of plists larger than a packet
- Return an error if failed to start a service on the device
- Fix usb enumeration
- Fix udev rule to catch usb hubs, too
- Add large file support
- Move out plist handling into libplist and depend on it
- Add Python bindings
- Lots of bugfixes
Version 0.1.0
~~~~~~~~~~~~~
* Changes:
- Use udev to set usb configuration; iphone kmod is obsolete now
- Remove HAL mounting
- Bugfixes

View File

@@ -1,196 +0,0 @@
# libimobiledevice
*A library to communicate with services on iOS devices using native protocols.*
![](https://github.com/libimobiledevice/libimobiledevice/actions/workflows/build.yml/badge.svg)
## Features
libimobiledevice is a cross-platform software library that talks the protocols
to interact with iOS devices.
Unlike other projects, it does not depend on using any existing proprietary
libraries and does not require jailbreaking.
Some key features are:
- **Interface**: Implements many high-level interfaces for device services
- **Implementation**: Object oriented architecture and service abstraction layer
- **Cross-Platform:** Tested on Linux, macOS, Windows and Android platforms
- **Utilities**: Provides various command-line utilities for device services
- **SSL**: Allows choosing between OpenSSL or GnuTLS to handle SSL communication
- **Network**: Supports network connections with "WiFi sync" enabled devices
- **Python:** Provides Cython based bindings for Python
The implemented interfaces of many device service protocols allow applications
to:
* Access filesystem of a device
* Access documents of file sharing apps
* Retrieve information about a device and modify various settings
* Backup and restore the device in a native way compatible with iTunes
* Manage app icons arrangement on the device
* Install, remove, list and basically manage apps
* Activate a device using official servers
* Manage contacts, calendars, notes and bookmarks
* Retrieve and remove crashreports
* Retrieve various diagnostics information
* Establish a debug connection for app debugging
* Mount filesystem images
* Forward device notifications
* Manage device provisioning
* Take screenshots from the device screen (requires mounted developer image)
* Simulate changed geolocation of the device (requires mounted developer image)
* Relay the syslog of the device
* Expose a connection for WebKit remote debugging
... and much more.
The library is in development since August 2007 with the goal to bring support
for these devices to the Linux Desktop.
## Installation / Getting started
### Debian / Ubuntu Linux
First install all required dependencies and build tools:
```shell
sudo apt-get install \
build-essential \
pkg-config \
checkinstall \
git \
autoconf \
automake \
libtool-bin \
libplist-dev \
libusbmuxd-dev \
libimobiledevice-glue-dev \
libssl-dev \
usbmuxd
```
If you want to optionally build the documentation or Python bindings use:
```shell
sudo apt-get install \
doxygen \
cython
```
Then clone the actual project repository:
```shell
git clone https://github.com/libimobiledevice/libimobiledevice.git
cd libimobiledevice
```
Now you can build and install it:
```shell
./autogen.sh
make
sudo make install
```
If you require a custom prefix or other option being passed to `./configure`
you can pass them directly to `./autogen.sh` like this:
```bash
./autogen.sh --prefix=/opt/local --enable-debug
make
sudo make install
```
By default, OpenSSL will be used as TLS/SSL library. If you prefer GnuTLS,
configure with `--with-gnutls` like this:
```bash
./autogen.sh --with-gnutls
```
MbedTLS is also supported and can be enabled by passing `--with-mbedtls` to
configure. If mbedTLS is not installed in a default location, you need to set
the environment variables `mbedtls_INCLUDES` to the path that contains the
MbedTLS headers and `mbedtls_LIBDIR` to set the library path. Optionally,
`mbedtls_LIBS` can be used to set the library names directly. Example:
```bash
./autogen.sh --with-mbedtls mbedtls_INCLUDES=/opt/local/include mbedtls_LIBDIR=/opt/local/lib
```
## Usage
Documentation about using the library in your application is not available yet.
The "hacker way" for now is to look at the implementation of the included
utilities.
### Utilities
The library bundles the following command-line utilities in the tools directory:
| Utility | Description |
| -------------------------- | ------------------------------------------------------------------ |
| `idevice_id` | List attached devices or print device name of given device |
| `idevicebackup` | Create or restore backup for devices (legacy) |
| `idevicebackup2` | Create or restore backups for devices running iOS 4 or later |
| `idevicebtlogger` | Capture Bluetooth HCI traffic from a device (requires log profile) |
| `idevicecrashreport` | Retrieve crash reports from a device |
| `idevicedate` | Display the current date or set it on a device |
| `idevicedebug` | Interact with the debugserver service of a device |
| `idevicedebugserverproxy` | Proxy a debugserver connection from a device for remote debugging |
| `idevicediagnostics` | Interact with the diagnostics interface of a device |
| `ideviceenterrecovery` | Make a device enter recovery mode |
| `ideviceimagemounter` | Mount disk images on the device |
| `ideviceinfo` | Show information about a connected device |
| `idevicename` | Display or set the device name |
| `idevicenotificationproxy` | Post or observe notifications on a device |
| `idevicepair` | Manage host pairings with devices and usbmuxd |
| `ideviceprovision` | Manage provisioning profiles on a device |
| `idevicescreenshot` | Gets a screenshot from the connected device |
| `idevicesetlocation` | Simulate location on device |
| `idevicesyslog` | Relay syslog of a connected device |
Please consult the usage information or manual pages of each utility for a
documentation of available command line options and usage examples like this:
```shell
ideviceinfo --help
man ideviceinfo
```
## Contributing
We welcome contributions from anyone and are grateful for every pull request!
If you'd like to contribute, please fork the `master` branch, change, commit and
send a pull request for review. Once approved it can be merged into the main
code base.
If you plan to contribute larger changes or a major refactoring, please create a
ticket first to discuss the idea upfront to ensure less effort for everyone.
Please make sure your contribution adheres to:
* Try to follow the code style of the project
* Commit messages should describe the change well without being too short
* Try to split larger changes into individual commits of a common domain
* Use your real name and a valid email address for your commits
We are still working on the guidelines so bear with us!
## Links
* Homepage: https://libimobiledevice.org/
* Repository: https://git.libimobiledevice.org/libimobiledevice.git
* Repository (Mirror): https://github.com/libimobiledevice/libimobiledevice.git
* Issue Tracker: https://github.com/libimobiledevice/libimobiledevice/issues
* Mailing List: https://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel
* Twitter: https://twitter.com/libimobiledev
## License
This library and utilities are licensed under the [GNU Lesser General Public License v2.1](https://www.gnu.org/licenses/lgpl-2.1.en.html),
also included in the repository in the `COPYING` file.
## Credits
Apple, iPhone, iPad, iPod, iPod Touch, Apple TV, Apple Watch, Mac, iOS,
iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc.
This project is an independent software and has not been authorized, sponsored,
or otherwise approved by Apple Inc.
README Updated on: 2022-04-04

View File

@@ -1,26 +0,0 @@
#!/bin/sh
olddir=`pwd`
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
(
cd "$srcdir"
gprefix=`which glibtoolize 2>&1 >/dev/null`
if [ $? -eq 0 ]; then
glibtoolize --force
else
libtoolize --force
fi
aclocal -I m4
autoheader
automake --add-missing
autoconf
cd "$olddir"
)
if [ -z "$NOCONFIGURE" ]; then
$srcdir/configure "$@"
fi

View File

@@ -1,33 +0,0 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
$(libusbmuxd_CFLAGS) \
$(libplist_CFLAGS) \
$(libgnutls_CFLAGS) \
$(libtasn1_CFLAGS) \
$(libgcrypt_CFLAGS) \
$(openssl_CFLAGS) \
$(LFS_CFLAGS)
AM_LDFLAGS = \
$(libusbmuxd_LIBS) \
$(libplist_LIBS) \
$(libgnutls_LIBS) \
$(libtasn1_LIBS) \
$(libgcrypt_LIBS) \
$(openssl_LIBS) \
${libpthread_LIBS}
noinst_LTLIBRARIES = libinternalcommon.la
libinternalcommon_la_LIBADD =
libinternalcommon_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined
libinternalcommon_la_SOURCES = \
debug.c debug.h \
userpref.c userpref.h
if WIN32
libinternalcommon_la_LIBADD += -lole32 -lws2_32
endif

View File

@@ -1,167 +0,0 @@
/*
* debug.c
* contains utilitary functions for debugging
*
* Copyright (c) 2008 Jonathan Beck All Rights Reserved.
* Copyright (c) 2010 Martin S. All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdarg.h>
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include "debug.h"
#include "libimobiledevice/libimobiledevice.h"
#include "src/idevice.h"
#ifndef STRIP_DEBUG_CODE
#include "asprintf.h"
#endif
static int debug_level;
void internal_set_debug_level(int level)
{
debug_level = level;
}
#define MAX_PRINT_LEN (16*1024)
#ifndef STRIP_DEBUG_CODE
static void debug_print_line(const char *func, const char *file, int line, const char *buffer)
{
char *str_time = NULL;
char *header = NULL;
time_t the_time;
time(&the_time);
str_time = (char*)malloc(255);
strftime(str_time, 254, "%H:%M:%S", localtime (&the_time));
/* generate header text */
(void)asprintf(&header, "%s %s:%d %s()", str_time, file, line, func);
free (str_time);
/* trim ending newlines */
/* print header */
fprintf(stderr, "%s: ", header);
/* print actual debug content */
fprintf(stderr, "%s\n", buffer);
free (header);
}
#endif
void debug_info_real(const char *func, const char *file, int line, const char *format, ...)
{
#ifndef STRIP_DEBUG_CODE
va_list args;
char *buffer = NULL;
if (!debug_level)
return;
/* run the real fprintf */
va_start(args, format);
(void)vasprintf(&buffer, format, args);
va_end(args);
debug_print_line(func, file, line, buffer);
free(buffer);
#endif
}
void debug_buffer(const char *data, const int length)
{
#ifndef STRIP_DEBUG_CODE
int i;
int j;
unsigned char c;
if (debug_level) {
for (i = 0; i < length; i += 16) {
fprintf(stderr, "%04x: ", i);
for (j = 0; j < 16; j++) {
if (i + j >= length) {
fprintf(stderr, " ");
continue;
}
fprintf(stderr, "%02x ", *(data + i + j) & 0xff);
}
fprintf(stderr, " | ");
for (j = 0; j < 16; j++) {
if (i + j >= length)
break;
c = *(data + i + j);
if ((c < 32) || (c > 127)) {
fprintf(stderr, ".");
continue;
}
fprintf(stderr, "%c", c);
}
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
#endif
}
void debug_buffer_to_file(const char *file, const char *data, const int length)
{
#ifndef STRIP_DEBUG_CODE
if (debug_level) {
FILE *f = fopen(file, "wb");
fwrite(data, 1, length, f);
fflush(f);
fclose(f);
}
#endif
}
void debug_plist_real(const char *func, const char *file, int line, plist_t plist)
{
#ifndef STRIP_DEBUG_CODE
if (!plist)
return;
char *buffer = NULL;
uint32_t length = 0;
plist_to_xml(plist, &buffer, &length);
/* get rid of ending newline as one is already added in the debug line */
if (buffer[length-1] == '\n')
buffer[length-1] = '\0';
if (length <= MAX_PRINT_LEN)
debug_info_real(func, file, line, "printing %i bytes plist:\n%s", length, buffer);
else
debug_info_real(func, file, line, "supress printing %i bytes plist...\n", length);
free(buffer);
#endif
}

View File

@@ -1,53 +0,0 @@
/*
* debug.h
* contains utilitary functions for debugging
*
* Copyright (c) 2008 Jonathan Beck All Rights Reserved.
* Copyright (c) 2010 Martin S. All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#include <plist/plist.h>
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && !defined(STRIP_DEBUG_CODE)
#define debug_info(...) debug_info_real (__func__, __FILE__, __LINE__, __VA_ARGS__)
#define debug_plist(a) debug_plist_real (__func__, __FILE__, __LINE__, a)
#elif defined(__GNUC__) && __GNUC__ >= 3 && !defined(STRIP_DEBUG_CODE)
#define debug_info(...) debug_info_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
#define debug_plist(a) debug_plist_real (__FUNCTION__, __FILE__, __LINE__, a)
#else
#define debug_info(...)
#define debug_plist(a)
#endif
void debug_info_real(const char *func,
const char *file,
int line,
const char *format, ...);
void debug_buffer(const char *data, const int length);
void debug_buffer_to_file(const char *file, const char *data, const int length);
void debug_plist_real(const char *func,
const char *file,
int line,
plist_t plist);
void internal_set_debug_level(int level);
#endif

View File

@@ -1,89 +0,0 @@
/*
* userpref.h
* contains methods to access user specific certificates IDs and more.
*
* Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved.
* Copyright (c) 2008 Jonathan Beck All Rights Reserved.
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __USERPREF_H
#define __USERPREF_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS)
typedef struct {
unsigned char *data;
unsigned int size;
} key_data_t;
#else
#include <gnutls/gnutls.h>
typedef gnutls_datum_t key_data_t;
#endif
#include <stdint.h>
#include <plist/plist.h>
#define USERPREF_DEVICE_CERTIFICATE_KEY "DeviceCertificate"
#define USERPREF_ESCROW_BAG_KEY "EscrowBag"
#define USERPREF_HOST_CERTIFICATE_KEY "HostCertificate"
#define USERPREF_ROOT_CERTIFICATE_KEY "RootCertificate"
#define USERPREF_HOST_PRIVATE_KEY_KEY "HostPrivateKey"
#define USERPREF_ROOT_PRIVATE_KEY_KEY "RootPrivateKey"
#define USERPREF_HOST_ID_KEY "HostID"
#define USERPREF_SYSTEM_BUID_KEY "SystemBUID"
#define USERPREF_WIFI_MAC_ADDRESS_KEY "WiFiMACAddress"
/** Error Codes */
typedef enum {
USERPREF_E_SUCCESS = 0,
USERPREF_E_INVALID_ARG = -1,
USERPREF_E_NOENT = -2,
USERPREF_E_INVALID_CONF = -3,
USERPREF_E_SSL_ERROR = -4,
USERPREF_E_READ_ERROR = -5,
USERPREF_E_WRITE_ERROR = -6,
USERPREF_E_UNKNOWN_ERROR = -256
} userpref_error_t;
const char *userpref_get_config_dir(void);
int userpref_read_system_buid(char **system_buid);
userpref_error_t userpref_read_pair_record(const char *udid, plist_t *pair_record);
userpref_error_t userpref_save_pair_record(const char *udid, uint32_t device_id, plist_t pair_record);
userpref_error_t userpref_delete_pair_record(const char *udid);
userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key);
#if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS)
userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key);
userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert);
#else
userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, gnutls_x509_privkey_t key);
userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, gnutls_x509_crt_t cert);
#endif
userpref_error_t pair_record_get_host_id(plist_t pair_record, char** host_id);
userpref_error_t pair_record_set_host_id(plist_t pair_record, const char* host_id);
userpref_error_t pair_record_get_item_as_key_data(plist_t pair_record, const char* name, key_data_t *value);
userpref_error_t pair_record_set_item_from_key_data(plist_t pair_record, const char* name, key_data_t *value);
/* deprecated */
userpref_error_t userpref_get_paired_udids(char ***list, unsigned int *count);
int userpref_has_pair_record(const char *udid);
#endif

View File

@@ -1,313 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([libimobiledevice], [m4_esyscmd(./git-version-gen $RELEASE_VERSION)], [https://github.com/libimobiledevice/libimobiledevice/issues], [], [https://libimobiledevice.org])
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip check-news])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
AC_CONFIG_SRCDIR([src/])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
dnl libtool versioning
# +1 : 0 : +1 == adds new functions to the interface
# +1 : 0 : 0 == changes or removes functions (changes include both
# changes to the signature and the semantic)
# ? :+1 : ? == just internal changes
# CURRENT : REVISION : AGE
LIBIMOBILEDEVICE_SO_VERSION=6:0:0
AC_SUBST(LIBIMOBILEDEVICE_SO_VERSION)
# Check if we have a version defined
if test -z $PACKAGE_VERSION; then
AC_MSG_ERROR([PACKAGE_VERSION is not defined. Make sure to configure a source tree checked out from git or that .tarball-version is present.])
fi
dnl Minimum package versions
LIBUSBMUXD_VERSION=2.0.2
LIBPLIST_VERSION=2.2.0
LIMD_GLUE_VERSION=1.0.0
AC_SUBST(LIBUSBMUXD_VERSION)
AC_SUBST(LIBPLIST_VERSION)
AC_SUBST(LIMD_GLUE_VERSION)
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AM_PROG_CC_C_O
LT_INIT
# Checks for libraries.
PKG_CHECK_MODULES(libusbmuxd, libusbmuxd-2.0 >= $LIBUSBMUXD_VERSION)
PKG_CHECK_MODULES(libplist, libplist-2.0 >= $LIBPLIST_VERSION)
PKG_CHECK_MODULES(limd_glue, libimobiledevice-glue-1.0 >= $LIMD_GLUE_VERSION)
# Checks for header files.
AC_CHECK_HEADERS([stdint.h stdlib.h string.h sys/time.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_CHECK_FUNCS([asprintf strcasecmp strdup strerror strndup stpcpy vasprintf getifaddrs])
AC_CHECK_HEADER(endian.h, [ac_cv_have_endian_h="yes"], [ac_cv_have_endian_h="no"])
if test "x$ac_cv_have_endian_h" = "xno"; then
AC_DEFINE(__LITTLE_ENDIAN,1234,[little endian])
AC_DEFINE(__BIG_ENDIAN,4321,[big endian])
AC_C_BIGENDIAN([ac_cv_c_bigendian="yes"], [ac_cv_c_bigendian="no"], [], [])
if test "x$ac_cv_c_bigendian" = "xyes"; then
AC_DEFINE(__BYTE_ORDER,4321,[big endian byte order])
else
AC_DEFINE(__BYTE_ORDER,1234,[little endian byte order])
fi
fi
AC_CHECK_DECL([plist_from_json], [AC_DEFINE([HAVE_PLIST_JSON], [1], [Define if libplist has JSON support])], [], [[#include <plist/plist.h>]])
# Check for operating system
AC_MSG_CHECKING([for platform-specific build settings])
case ${host_os} in
*mingw32*|*cygwin*)
AC_MSG_RESULT([${host_os}])
win32=true
AC_DEFINE(WINVER, 0x0501, [minimum Windows version])
;;
darwin*)
AC_MSG_RESULT([${host_os}])
darwin=true
;;
*)
AC_MSG_RESULT([${host_os}])
AX_PTHREAD([], [AC_MSG_ERROR([pthread is required to build $PACKAGE_NAME])])
AC_CHECK_LIB(pthread, [pthread_once], [], [AC_MSG_ERROR([pthread with pthread_once required to build $PACKAGE_NAME])])
;;
esac
AM_CONDITIONAL(WIN32, test x$win32 = xtrue)
AM_CONDITIONAL(DARWIN, test x$darwin = xtrue)
# Check if the C compiler supports __attribute__((constructor))
AC_CACHE_CHECK([wether the C compiler supports constructor/destructor attributes],
ac_cv_attribute_constructor, [
ac_cv_attribute_constructor=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
static void __attribute__((constructor)) test_constructor(void) {
}
static void __attribute__((destructor)) test_destructor(void) {
}
]], [])],
[ac_cv_attribute_constructor=yes]
)]
)
if test "$ac_cv_attribute_constructor" = "yes"; then
AC_DEFINE(HAVE_ATTRIBUTE_CONSTRUCTOR, 1, [Define if the C compiler supports constructor/destructor attributes])
fi
AC_CHECK_MEMBER(struct dirent.d_type, AC_DEFINE(HAVE_DIRENT_D_TYPE, 1, [define if struct dirent has member d_type]),, [#include <dirent.h>])
# Cython Python Bindings
AC_ARG_WITH([cython],
[AS_HELP_STRING([--without-cython],
[build Python bindings using Cython (default is yes)])],
[build_cython=false],
[build_cython=true])
if test "$build_cython" = "true"; then
AC_PROG_CYTHON([0.17.0])
if [test "x$CYTHON" != "xfalse"]; then
AM_PATH_PYTHON([2.3], [
CYTHON_PYTHON
AS_COMPILER_FLAG([-Wno-cast-function-type -Werror], [
CYTHON_CFLAGS+=" -Wno-cast-function-type"
AC_SUBST([CYTHON_CFLAGS])
], [])
])
else
AC_MSG_WARN([Use the "--without-cython" option to avoid this warning.])
fi
else
CYTHON=false
fi
if [test "x$CYTHON" != "xfalse"]; then
PKG_PROG_PKG_CONFIG
AC_MSG_CHECKING([for libplist Cython bindings])
CYTHON_PLIST_INCLUDE_DIR=$($PKG_CONFIG --variable=includedir libplist-2.0)/plist/cython
if [test ! -d "$CYTHON_PLIST_INCLUDE_DIR"]; then
CYTHON=false
CYTHON_SUB=
cython_python_bindings=no
AC_MSG_RESULT([no])
AC_MSG_WARN([Unable to find libplist Cython bindings. You should install your distribution specific libplist Cython bindings package.])
else
AC_SUBST([CYTHON_PLIST_INCLUDE_DIR])
AC_MSG_RESULT([$CYTHON_PLIST_INCLUDE_DIR])
CYTHON_SUB=cython
cython_python_bindings=yes
fi
else
CYTHON_SUB=
cython_python_bindings=no
fi
AM_CONDITIONAL([HAVE_CYTHON],[test "x$CYTHON_SUB" = "xcython"])
AC_SUBST([CYTHON_SUB])
default_openssl=yes
AC_ARG_WITH([mbedtls],
[AS_HELP_STRING([--without-mbedtls],
[Do not look for mbedtls])],
[use_mbedtls=$withval],
[use_mbedtls=no])
if test "x$use_mbedtls" == "xyes"; then
default_openssl=no
fi
AC_ARG_WITH([gnutls],
[AS_HELP_STRING([--without-gnutls],
[Do not look for GnuTLS])],
[use_gnutls=$withval],
[use_gnutls=no])
if test "x$use_gnutls" == "xyes"; then
default_openssl=no
fi
AC_ARG_WITH([openssl],
[AS_HELP_STRING([--without-openssl],
[Do not look for OpenSSL])],
[use_openssl=$withval],
[use_openssl=$default_openssl])
if test "x$use_mbedtls" == "xyes"; then
CACHED_CFLAGS="$CFLAGS"
conf_mbedtls_CFLAGS=""
if test -n "$mbedtls_INCLUDES"; then
CFLAGS=" -I$mbedtls_INCLUDES"
conf_mbedtls_CFLAGS="-I$mbedtls_INCLUDES"
fi
conf_mbedtls_LIBS=""
if test -n "$mbedtls_LIBDIR"; then
conf_mbedtls_LIBS+=" -L$mbedtls_LIBDIR"
fi
if test -n "$mbedtls_LIBS"; then
conf_mbedtls_LIBS+=" $mbedtls_LIBS"
else
conf_mbedtls_LIBS+=" -lmbedtls -lmbedx509 -lmbedcrypto"
fi
AC_CHECK_HEADER(mbedtls/ssl.h, [break], [AC_MSG_ERROR([MbedTLS support explicitly requested, but includes could not be found. Try setting mbedtls_INCLUDES=/path/to/mbedtls/include])])
CFLAGS="$CACHED_CFLAGS"
AC_DEFINE(HAVE_MBEDTLS, 1, [Define if you have MbedTLS support])
ssl_lib_CFLAGS="$conf_mbedtls_CFLAGS"
ssl_lib_LIBS="$conf_mbedtls_LIBS"
AC_SUBST(ssl_lib_CFLAGS)
AC_SUBST(ssl_lib_LIBS)
ssl_provider="MbedTLS";
ssl_requires=""
AC_SUBST(ssl_requires)
else
if test "x$use_openssl" == "xyes"; then
pkg_req_openssl="openssl >= 0.9.8"
PKG_CHECK_MODULES(openssl, $pkg_req_openssl, have_openssl=yes, have_openssl=no)
if test "x$have_openssl" != "xyes"; then
AC_MSG_ERROR([OpenSSL support explicitly requested but OpenSSL could not be found])
else
AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have OpenSSL support])
ssl_lib_CFLAGS="$openssl_CFLAGS"
ssl_lib_LIBS="$openssl_LIBS"
AC_SUBST(ssl_lib_CFLAGS)
AC_SUBST(ssl_lib_LIBS)
ssl_provider="OpenSSL";
ssl_requires="$pkg_req_openssl"
AC_SUBST(ssl_requires)
fi
else
if test "x$use_gnutls" == "xyes"; then
pkg_req_gnutls="gnutls >= 2.2.0"
pkg_req_libtasn1="libtasn1 >= 1.1"
PKG_CHECK_MODULES(libgnutls, $pkg_req_gnutls)
AC_CHECK_HEADERS([gcrypt.h])
AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], [AC_MSG_ERROR([libgcrypt is required to build libimobiledevice with GnuTLS])])
PKG_CHECK_MODULES(libtasn1, $pkg_req_libtasn1)
AC_DEFINE(HAVE_GCRYPT, 1, [Define if you have libgcrypt support])
AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS support])
ssl_lib_CFLAGS="$libgnutls_CFLAGS $libtasn1_CFLAGS $libgcrypt_CFLAGS"
ssl_lib_LIBS="$libgnutls_LIBS $libtasn1_LIBS $libgcrypt_LIBS"
AC_SUBST(ssl_lib_CFLAGS)
AC_SUBST(ssl_lib_LIBS)
ssl_provider="GnuTLS"
ssl_requires="$pkg_req_gnutls $pkg_req_libtasn1"
AC_SUBST(ssl_requires)
else
AC_MSG_ERROR([No SSL library configured. $PACKAGE cannot be built without a supported SSL library.])
fi
fi
fi
AM_CONDITIONAL(HAVE_MBEDTLS, test "x$use_mbedtls" == "xyes")
AM_CONDITIONAL(HAVE_OPENSSL, test "x$use_openssl" == "xyes")
AM_CONDITIONAL(HAVE_GCRYPT, test "x$use_gnutls" == "xyes")
AC_ARG_ENABLE([wireless-pairing],
[AS_HELP_STRING([--disable-wireless-pairing],
[Do not build with wirless pairing support (default is yes)])])
if test "$enable_wireless_pairing" != "no"; then
AC_DEFINE(HAVE_WIRELESS_PAIRING,1,[Define if building with wireless pairing support])
fi
AM_CONDITIONAL(HAVE_WIRELESS_PAIRING, test "$enable_wireless_pairing" != "no")
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug],
[build debug message output code (default is no)])],
[no_debug_code=false],
[no_debug_code=true])
if test "$no_debug_code" = true; then
building_debug_code=no
AC_DEFINE(STRIP_DEBUG_CODE,1,[Define if debug message output code should not be built.])
else
building_debug_code=yes
fi
AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter -fsigned-char -fvisibility=hidden")
AC_SUBST(GLOBAL_CFLAGS)
case "$GLOBAL_CFLAGS" in
*-fvisibility=hidden*)
AC_DEFINE([HAVE_FVISIBILITY], [1], [Define if compiled with -fvisibility=hidden])
esac
# check for large file support
AC_SYS_LARGEFILE
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_CONFIG_FILES([
Makefile
3rd_party/Makefile
3rd_party/ed25519/Makefile
3rd_party/libsrp6a-sha512/Makefile
common/Makefile
src/Makefile
src/libimobiledevice-1.0.pc
include/Makefile
tools/Makefile
cython/Makefile
docs/Makefile
doxygen.cfg
])
AC_OUTPUT
echo "
Configuration for $PACKAGE $VERSION:
-------------------------------------------
Install prefix: .........: $prefix
Debug code ..............: $building_debug_code
Python bindings .........: $cython_python_bindings
SSL support backend .....: $ssl_provider
Now type 'make' to build $PACKAGE $VERSION,
and then 'make install' for installation.
"

View File

@@ -1,88 +0,0 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/include
AM_CFLAGS = \
$(GLOBAL_CFLAGS) \
$(libgnutls_CFLAGS) \
$(libtasn1_CFLAGS) \
$(openssl_CFLAGS) \
$(libplist_CFLAGS) \
$(LFS_CFLAGS) \
$(PTHREAD_CFLAGS)
AM_LIBS = \
$(libgnutls_LIBS) \
$(libtasn1_LIBS) \
$(openssl_LIBS) \
$(libplist_LIBS) \
$(PTHREAD_LIBS)
if HAVE_CYTHON
BUILT_SOURCES = imobiledevice.c
PXDINCLUDES = \
imobiledevice.pxd \
$(CYTHON_PLIST_INCLUDE_DIR)/plist.pxd
PXIINCLUDES = \
lockdown.pxi \
mobilesync.pxi \
notification_proxy.pxi \
sbservices.pxi \
mobilebackup.pxi \
mobilebackup2.pxi \
afc.pxi \
file_relay.pxi \
screenshotr.pxi \
installation_proxy.pxi \
webinspector.pxi \
heartbeat.pxi \
diagnostics_relay.pxi \
misagent.pxi \
house_arrest.pxi \
restore.pxi \
mobile_image_mounter.pxi \
debugserver.pxi
CLEANFILES = \
*.pyc \
*.pyo \
imobiledevice.c
EXTRA_DIST = \
imobiledevice.pyx \
imobiledevice.pxd \
$(PXIINCLUDES)
imobiledevicedir = $(pyexecdir)
imobiledevice_LTLIBRARIES = imobiledevice.la
imobiledevice_la_SOURCES = imobiledevice.pyx
imobiledevice_la_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
$(PYTHON_CPPFLAGS) \
$(AM_CFLAGS) \
-Wno-shadow \
-Wno-redundant-decls \
-Wno-switch-default \
-Wno-strict-aliasing \
-Wno-implicit-function-declaration \
-fvisibility=default \
$(CYTHON_CFLAGS)
imobiledevice_la_LDFLAGS = \
-module \
-avoid-version \
-L$(libdir) \
$(PYTHON_LIBS) \
$(AM_LIBS) \
-no-undefined
imobiledevice_la_LIBADD = $(top_builddir)/src/libimobiledevice-1.0.la
imobiledevice.c: imobiledevice.pyx $(PXDINCLUDES) $(PXIINCLUDES)
.pyx.c:
$(CYTHON) -I$(CYTHON_PLIST_INCLUDE_DIR) -I$(top_srcdir)/src -o $@ $<
endif

View File

@@ -1,337 +0,0 @@
cdef extern from "libimobiledevice/afc.h":
cdef struct afc_client_private:
pass
ctypedef afc_client_private *afc_client_t
ctypedef enum afc_error_t:
AFC_E_SUCCESS = 0
AFC_E_UNKNOWN_ERROR = 1
AFC_E_OP_HEADER_INVALID = 2
AFC_E_NO_RESOURCES = 3
AFC_E_READ_ERROR = 4
AFC_E_WRITE_ERROR = 5
AFC_E_UNKNOWN_PACKET_TYPE = 6
AFC_E_INVALID_ARG = 7
AFC_E_OBJECT_NOT_FOUND = 8
AFC_E_OBJECT_IS_DIR = 9
AFC_E_PERM_DENIED = 10
AFC_E_SERVICE_NOT_CONNECTED = 11
AFC_E_OP_TIMEOUT = 12
AFC_E_TOO_MUCH_DATA = 13
AFC_E_END_OF_DATA = 14
AFC_E_OP_NOT_SUPPORTED = 15
AFC_E_OBJECT_EXISTS = 16
AFC_E_OBJECT_BUSY = 17
AFC_E_NO_SPACE_LEFT = 18
AFC_E_OP_WOULD_BLOCK = 19
AFC_E_IO_ERROR = 20
AFC_E_OP_INTERRUPTED = 21
AFC_E_OP_IN_PROGRESS = 22
AFC_E_INTERNAL_ERROR = 23
AFC_E_MUX_ERROR = 30
AFC_E_NO_MEM = 31
AFC_E_NOT_ENOUGH_DATA = 32
AFC_E_DIR_NOT_EMPTY = 33
ctypedef enum afc_file_mode_t:
AFC_FOPEN_RDONLY = 0x00000001
AFC_FOPEN_RW = 0x00000002
AFC_FOPEN_WRONLY = 0x00000003
AFC_FOPEN_WR = 0x00000004
AFC_FOPEN_APPEND = 0x00000005
AFC_FOPEN_RDAPPEND = 0x00000006
ctypedef enum afc_link_type_t:
AFC_HARDLINK = 1
AFC_SYMLINK = 2
ctypedef enum afc_lock_op_t:
AFC_LOCK_SH = 1 | 4
AFC_LOCK_EX = 2 | 4
AFC_LOCK_UN = 8 | 4
afc_error_t afc_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, afc_client_t *client)
afc_error_t afc_client_free(afc_client_t client)
afc_error_t afc_get_device_info(afc_client_t client, char ***infos)
afc_error_t afc_read_directory(afc_client_t client, char *dir, char ***list)
afc_error_t afc_get_file_info(afc_client_t client, char *filename, char ***infolist)
afc_error_t afc_remove_path(afc_client_t client, char *path)
afc_error_t afc_remove_path_and_contents(afc_client_t client, char *path)
afc_error_t afc_rename_path(afc_client_t client, char *f, char *to)
afc_error_t afc_make_directory(afc_client_t client, char *dir)
afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize)
afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, char *target, char *linkname)
afc_error_t afc_set_file_time(afc_client_t client, char *path, uint64_t mtime)
afc_error_t afc_file_open(afc_client_t client, char *filename, afc_file_mode_t file_mode, uint64_t *handle)
afc_error_t afc_file_close(afc_client_t client, uint64_t handle)
afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read)
afc_error_t afc_file_write(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_written)
afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence)
afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position)
afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
LOCK_SH = AFC_LOCK_SH
LOCK_EX = AFC_LOCK_EX
LOCK_UN = AFC_LOCK_UN
cdef class AfcError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
AFC_E_SUCCESS: "Success",
AFC_E_UNKNOWN_ERROR: "Unknown error",
AFC_E_OP_HEADER_INVALID: "OP header invalid",
AFC_E_NO_RESOURCES: "No resources",
AFC_E_READ_ERROR: "Read error",
AFC_E_WRITE_ERROR: "Write error",
AFC_E_UNKNOWN_PACKET_TYPE: "Unknown packet type",
AFC_E_INVALID_ARG: "Invalid argument",
AFC_E_OBJECT_NOT_FOUND: "Object not found",
AFC_E_OBJECT_IS_DIR: "Object is directory",
AFC_E_PERM_DENIED: "Permission denied",
AFC_E_SERVICE_NOT_CONNECTED: "Service not connected",
AFC_E_OP_TIMEOUT: "OP timeout",
AFC_E_TOO_MUCH_DATA: "Too much data",
AFC_E_END_OF_DATA: "End of data",
AFC_E_OP_NOT_SUPPORTED: "OP not supported",
AFC_E_OBJECT_EXISTS: "Object exists",
AFC_E_OBJECT_BUSY: "Object busy",
AFC_E_NO_SPACE_LEFT: "No space left",
AFC_E_OP_WOULD_BLOCK: "OP would block",
AFC_E_IO_ERROR: "IO error",
AFC_E_OP_INTERRUPTED: "OP interrupted",
AFC_E_OP_IN_PROGRESS: "OP in progress",
AFC_E_INTERNAL_ERROR: "Internal error",
AFC_E_MUX_ERROR: "MUX error",
AFC_E_NO_MEM: "No memory",
AFC_E_NOT_ENOUGH_DATA: "Not enough data",
AFC_E_DIR_NOT_EMPTY: "Directory not empty"
}
BaseError.__init__(self, *args, **kwargs)
# forward declaration of AfcClient
cdef class AfcClient(BaseService)
cdef class AfcFile(Base):
cdef uint64_t _c_handle
cdef AfcClient _client
cdef bytes _filename
def __init__(self, *args, **kwargs):
raise TypeError("AfcFile cannot be instantiated")
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
cpdef close(self):
self.handle_error(afc_file_close(self._client._c_client, self._c_handle))
cpdef lock(self, int operation):
self.handle_error(afc_file_lock(self._client._c_client, self._c_handle, <afc_lock_op_t>operation))
cpdef seek(self, int64_t offset, int whence):
self.handle_error(afc_file_seek(self._client._c_client, self._c_handle, offset, whence))
cpdef uint64_t tell(self):
cdef uint64_t position
self.handle_error(afc_file_tell(self._client._c_client, self._c_handle, &position))
return position
cpdef truncate(self, uint64_t newsize):
self.handle_error(afc_file_truncate(self._client._c_client, self._c_handle, newsize))
cpdef bytes read(self, uint32_t size):
cdef:
uint32_t bytes_read
char* c_data = <char *>malloc(size)
bytes result
try:
self.handle_error(afc_file_read(self._client._c_client, self._c_handle, c_data, size, &bytes_read))
result = c_data[:bytes_read]
return result
except BaseError, e:
raise
finally:
free(c_data)
cpdef uint32_t write(self, bytes data):
cdef:
uint32_t bytes_written
char* c_data = data
try:
self.handle_error(afc_file_write(self._client._c_client, self._c_handle, c_data, len(data), &bytes_written))
except BaseError, e:
raise
return bytes_written
cdef inline BaseError _error(self, int16_t ret):
return AfcError(ret)
cdef class AfcClient(BaseService):
__service_name__ = "com.apple.afc"
cdef afc_client_t _c_client
def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs):
if (device is not None and descriptor is not None):
self.handle_error(afc_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
def __dealloc__(self):
cdef afc_error_t err
if self._c_client is not NULL:
err = afc_client_free(self._c_client)
self.handle_error(err)
cdef BaseError _error(self, int16_t ret):
return AfcError(ret)
cpdef list get_device_info(self):
cdef:
afc_error_t err
char** infos = NULL
bytes info
int i = 0
list result = []
err = afc_get_device_info(self._c_client, &infos)
try:
self.handle_error(err)
except BaseError, e:
raise
finally:
if infos != NULL:
while infos[i]:
info = infos[i]
result.append(info)
free(infos[i])
i = i + 1
free(infos)
return result
cpdef list read_directory(self, bytes directory):
cdef:
afc_error_t err
char** dir_list = NULL
bytes f
int i = 0
list result = []
err = afc_read_directory(self._c_client, directory, &dir_list)
try:
self.handle_error(err)
except BaseError, e:
raise
finally:
if dir_list != NULL:
while dir_list[i]:
f = dir_list[i]
result.append(f)
free(dir_list[i])
i = i + 1
free(dir_list)
return result
cpdef AfcFile open(self, bytes filename, bytes mode=b'r'):
cdef:
afc_file_mode_t c_mode
uint64_t handle
AfcFile f
if mode == b'r':
c_mode = AFC_FOPEN_RDONLY
elif mode == b'r+':
c_mode = AFC_FOPEN_RW
elif mode == b'w':
c_mode = AFC_FOPEN_WRONLY
elif mode == b'w+':
c_mode = AFC_FOPEN_WR
elif mode == b'a':
c_mode = AFC_FOPEN_APPEND
elif mode == b'a+':
c_mode = AFC_FOPEN_RDAPPEND
else:
raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'")
self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle))
f = AfcFile.__new__(AfcFile)
f._c_handle = handle
f._client = self
f._filename = filename
return f
cpdef list get_file_info(self, bytes path):
cdef:
list result = []
char** c_result = NULL
int i = 0
bytes info
try:
self.handle_error(afc_get_file_info(self._c_client, path, &c_result))
except BaseError, e:
raise
finally:
if c_result != NULL:
while c_result[i]:
info = c_result[i]
result.append(info)
free(c_result[i])
i = i + 1
free(c_result)
return result
cpdef remove_path(self, bytes path):
self.handle_error(afc_remove_path(self._c_client, path))
cpdef remove_path_and_contents(self, bytes path):
self.handle_error(afc_remove_path_and_contents(self._c_client, path))
cpdef rename_path(self, bytes f, bytes t):
self.handle_error(afc_rename_path(self._c_client, f, t))
cpdef make_directory(self, bytes d):
self.handle_error(afc_make_directory(self._c_client, d))
cpdef truncate(self, bytes path, uint64_t newsize):
self.handle_error(afc_truncate(self._c_client, path, newsize))
cpdef link(self, bytes source, bytes link_name):
self.handle_error(afc_make_link(self._c_client, AFC_HARDLINK, source, link_name))
cpdef symlink(self, bytes source, bytes link_name):
self.handle_error(afc_make_link(self._c_client, AFC_SYMLINK, source, link_name))
cpdef set_file_time(self, bytes path, uint64_t mtime):
self.handle_error(afc_set_file_time(self._c_client, path, mtime))
cdef class Afc2Client(AfcClient):
__service_name__ = "com.apple.afc2"
cpdef AfcFile open(self, bytes filename, bytes mode=b'r'):
cdef:
afc_file_mode_t c_mode
uint64_t handle
AfcFile f
if mode == b'r':
c_mode = AFC_FOPEN_RDONLY
elif mode == b'r+':
c_mode = AFC_FOPEN_RW
elif mode == b'w':
c_mode = AFC_FOPEN_WRONLY
elif mode == b'w+':
c_mode = AFC_FOPEN_WR
elif mode == b'a':
c_mode = AFC_FOPEN_APPEND
elif mode == b'a+':
c_mode = AFC_FOPEN_RDAPPEND
else:
raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'")
self.handle_error(afc_file_open(self._c_client, filename, c_mode, &handle))
f = AfcFile.__new__(AfcFile)
f._c_handle = handle
f._client = <AfcClient>self
f._filename = filename
return f

View File

@@ -1,252 +0,0 @@
cdef extern from "libimobiledevice/debugserver.h":
cdef struct debugserver_client_private:
pass
ctypedef debugserver_client_private *debugserver_client_t
cdef struct debugserver_command_private:
pass
ctypedef debugserver_command_private *debugserver_command_t
ctypedef enum debugserver_error_t:
DEBUGSERVER_E_SUCCESS = 0
DEBUGSERVER_E_INVALID_ARG = -1
DEBUGSERVER_E_MUX_ERROR = -2
DEBUGSERVER_E_SSL_ERROR = -3
DEBUGSERVER_E_RESPONSE_ERROR = -4
DEBUGSERVER_E_UNKNOWN_ERROR = -256
debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t * client)
debugserver_error_t debugserver_client_free(debugserver_client_t client)
debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent)
debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response, size_t* response_size)
debugserver_error_t debugserver_client_receive(debugserver_client_t client, char *data, uint32_t size, uint32_t *received)
debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout)
debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size)
debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response)
debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response)
debugserver_error_t debugserver_command_new(const char* name, int argc, const char* argv[], debugserver_command_t* command)
debugserver_error_t debugserver_command_free(debugserver_command_t command)
void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length)
void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer)
cdef class DebugServerError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
DEBUGSERVER_E_SUCCESS: "Success",
DEBUGSERVER_E_INVALID_ARG: "Invalid argument",
DEBUGSERVER_E_MUX_ERROR: "MUX error",
DEBUGSERVER_E_SSL_ERROR: "SSL error",
DEBUGSERVER_E_RESPONSE_ERROR: "Response error",
DEBUGSERVER_E_UNKNOWN_ERROR: "Unknown error",
}
BaseError.__init__(self, *args, **kwargs)
# from http://stackoverflow.com/a/17511714
# https://github.com/libimobiledevice/libimobiledevice/pull/198
from cpython cimport PY_MAJOR_VERSION
if PY_MAJOR_VERSION <= 2:
from cpython.string cimport PyString_AsString
else:
from cpython.bytes cimport PyBytes_AsString as PyString_AsString
cdef char ** to_cstring_array(list_str):
if not list_str:
return NULL
cdef char **ret = <char **>malloc(len(list_str) * sizeof(char *))
for i in xrange(len(list_str)):
ret[i] = PyString_AsString(list_str[i])
return ret
cdef class DebugServerCommand(Base):
cdef debugserver_command_t _c_command
def __init__(self, bytes name, int argc = 0, argv = None, *args, **kwargs):
cdef:
char* c_name = name
char** c_argv = to_cstring_array(argv)
try:
self.handle_error(debugserver_command_new(c_name, argc, c_argv, &self._c_command))
except BaseError, e:
raise
finally:
free(c_argv)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.free()
cdef free(self):
cdef debugserver_error_t err
if self._c_command is not NULL:
err = debugserver_command_free(self._c_command)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return DebugServerError(ret)
cdef class DebugServerClient(BaseService):
__service_name__ = "com.apple.debugserver"
cdef debugserver_client_t _c_client
def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs):
if (device is not None and descriptor is not None):
self.handle_error(debugserver_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
def __dealloc__(self):
cdef debugserver_error_t err
if self._c_client is not NULL:
err = debugserver_client_free(self._c_client)
self.handle_error(err)
cdef BaseError _error(self, int16_t ret):
return DebugServerError(ret)
cpdef uint32_t send(self, bytes data):
cdef:
uint32_t bytes_send
char* c_data = data
try:
self.handle_error(debugserver_client_send(self._c_client, c_data, len(data), &bytes_send))
except BaseError, e:
raise
return bytes_send
cpdef bytes send_command(self, DebugServerCommand command):
cdef:
char* c_response = NULL
bytes result
try:
self.handle_error(debugserver_client_send_command(self._c_client, command._c_command, &c_response, NULL))
if c_response:
result = c_response
return result
else:
return None
except BaseError, e:
raise
finally:
free(c_response)
cpdef bytes receive(self, uint32_t size):
cdef:
uint32_t bytes_received
char* c_data = <char *>malloc(size)
bytes result
try:
self.handle_error(debugserver_client_receive(self._c_client, c_data, size, &bytes_received))
result = c_data[:bytes_received]
return result
except BaseError, e:
raise
finally:
free(c_data)
cpdef bytes receive_with_timeout(self, uint32_t size, unsigned int timeout):
cdef:
uint32_t bytes_received
char* c_data = <char *>malloc(size)
bytes result
try:
self.handle_error(debugserver_client_receive_with_timeout(self._c_client, c_data, size, &bytes_received, timeout))
result = c_data[:bytes_received]
return result
except BaseError, e:
raise
finally:
free(c_data)
cpdef bytes receive_response(self):
cdef:
char* c_response = NULL
bytes result
try:
self.handle_error(debugserver_client_receive_response(self._c_client, &c_response, NULL))
if c_response:
result = c_response
return result
else:
return None
except BaseError, e:
raise
finally:
free(c_response)
cpdef bytes set_argv(self, int argc, argv):
cdef:
char** c_argv = to_cstring_array(argv)
char* c_response = NULL
bytes result
try:
self.handle_error(debugserver_client_set_argv(self._c_client, argc, c_argv, &c_response))
if c_response:
result = c_response
return result
else:
return None
except BaseError, e:
raise
finally:
free(c_argv)
free(c_response)
cpdef bytes set_environment_hex_encoded(self, bytes env):
cdef:
char* c_env = env
char* c_response = NULL
bytes result
try:
self.handle_error(debugserver_client_set_environment_hex_encoded(self._c_client, c_env, &c_response))
if c_response:
result = c_response
return result
else:
return None
except BaseError, e:
raise
finally:
free(c_response)
cpdef bytes encode_string(self, bytes buffer):
cdef:
char *c_buffer = buffer
uint32_t encoded_length = len(c_buffer) * 2 + 0x3 + 1
char* c_encoded_buffer = <char *>malloc(encoded_length)
bytes result
try:
debugserver_encode_string(c_buffer, &c_encoded_buffer, &encoded_length)
result = c_encoded_buffer[:encoded_length]
return result
except BaseError, e:
raise
finally:
free(c_encoded_buffer)
cpdef bytes decode_string(self, bytes encoded_buffer):
cdef:
char* c_encoded_buffer = encoded_buffer
uint32_t encoded_length = len(c_encoded_buffer)
char *c_buffer = <char *>malloc(encoded_length)
bytes result
try:
debugserver_decode_string(c_encoded_buffer, encoded_length, &c_buffer)
result = c_buffer
return result
except BaseError, e:
raise
finally:
free(c_buffer)

View File

@@ -1,128 +0,0 @@
REQUEST_TYPE_ALL = "All"
REQUEST_TYPE_WIFI = "WiFi"
REQUEST_TYPE_GAS_GAUGE = "GasGauge"
REQUEST_TYPE_NAND = "NAND"
cdef extern from "libimobiledevice/diagnostics_relay.h":
cdef struct diagnostics_relay_client_private:
pass
ctypedef diagnostics_relay_client_private *diagnostics_relay_client_t
ctypedef enum diagnostics_relay_error_t:
DIAGNOSTICS_RELAY_E_SUCCESS = 0
DIAGNOSTICS_RELAY_E_INVALID_ARG = -1
DIAGNOSTICS_RELAY_E_PLIST_ERROR = -2
DIAGNOSTICS_RELAY_E_MUX_ERROR = -3
DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST = -4
DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR = -256
ctypedef enum diagnostics_relay_action_t:
DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT = (1 << 1)
DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS = (1 << 2)
DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL = (1 << 3)
diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, diagnostics_relay_client_t * client)
diagnostics_relay_error_t diagnostics_relay_client_free(diagnostics_relay_client_t client)
diagnostics_relay_error_t diagnostics_relay_goodbye(diagnostics_relay_client_t client)
diagnostics_relay_error_t diagnostics_relay_sleep(diagnostics_relay_client_t client)
diagnostics_relay_error_t diagnostics_relay_restart(diagnostics_relay_client_t client, diagnostics_relay_action_t flags)
diagnostics_relay_error_t diagnostics_relay_shutdown(diagnostics_relay_client_t client, diagnostics_relay_action_t flags)
diagnostics_relay_error_t diagnostics_relay_request_diagnostics(diagnostics_relay_client_t client, char* type, plist.plist_t* diagnostics)
diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist.plist_t keys, plist.plist_t* result)
diagnostics_relay_error_t diagnostics_relay_query_ioregistry_entry(diagnostics_relay_client_t client, char* name, char* class_name, plist.plist_t* result)
diagnostics_relay_error_t diagnostics_relay_query_ioregistry_plane(diagnostics_relay_client_t client, char* plane, plist.plist_t* result)
cdef class DiagnosticsRelayError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
DIAGNOSTICS_RELAY_E_SUCCESS: "Success",
DIAGNOSTICS_RELAY_E_INVALID_ARG: "Invalid argument",
DIAGNOSTICS_RELAY_E_PLIST_ERROR: "Property list error",
DIAGNOSTICS_RELAY_E_MUX_ERROR: "MUX error",
DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST: "Unknown request",
DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class DiagnosticsRelayClient(PropertyListService):
__service_name__ = "com.apple.mobile.diagnostics_relay"
cdef diagnostics_relay_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(diagnostics_relay_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef diagnostics_relay_error_t err
if self._c_client is not NULL:
err = diagnostics_relay_client_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return DiagnosticsRelayError(ret)
cpdef goodbye(self):
self.handle_error(diagnostics_relay_goodbye(self._c_client))
cpdef sleep(self):
self.handle_error(diagnostics_relay_sleep(self._c_client))
cpdef restart(self, diagnostics_relay_action_t flags):
self.handle_error(diagnostics_relay_restart(self._c_client, flags))
cpdef shutdown(self, diagnostics_relay_action_t flags):
self.handle_error(diagnostics_relay_shutdown(self._c_client, flags))
cpdef plist.Node request_diagnostics(self, bytes type):
cdef:
plist.plist_t c_node = NULL
diagnostics_relay_error_t err
err = diagnostics_relay_request_diagnostics(self._c_client, type, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef plist.Node query_mobilegestalt(self, plist.Node keys = None):
cdef:
plist.plist_t c_node = NULL
diagnostics_relay_error_t err
plist.plist_t keys_c_node = NULL
if keys is not None:
keys_c_node = keys._c_node
err = diagnostics_relay_query_mobilegestalt(self._c_client, keys_c_node, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef plist.Node query_ioregistry_entry(self, bytes name, bytes class_name):
cdef:
plist.plist_t c_node = NULL
diagnostics_relay_error_t err
err = diagnostics_relay_query_ioregistry_entry(self._c_client, name, class_name, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef plist.Node query_ioregistry_plane(self, bytes plane = None):
cdef:
plist.plist_t c_node = NULL
diagnostics_relay_error_t err
err = diagnostics_relay_query_ioregistry_plane(self._c_client, plane, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise

View File

@@ -1,68 +0,0 @@
cdef extern from "libimobiledevice/file_relay.h":
cdef struct file_relay_client_private:
pass
ctypedef file_relay_client_private *file_relay_client_t
ctypedef char** const_sources_t "const char**"
ctypedef enum file_relay_error_t:
FILE_RELAY_E_SUCCESS = 0
FILE_RELAY_E_INVALID_ARG = -1
FILE_RELAY_E_PLIST_ERROR = -2
FILE_RELAY_E_MUX_ERROR = -3
FILE_RELAY_E_INVALID_SOURCE = -4
FILE_RELAY_E_STAGING_EMPTY = -5
FILE_RELAY_E_PERMISSION_DENIED = -6
FILE_RELAY_E_UNKNOWN_ERROR = -256
file_relay_error_t file_relay_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, file_relay_client_t *client)
file_relay_error_t file_relay_client_free(file_relay_client_t client)
file_relay_error_t file_relay_request_sources(file_relay_client_t client, const_sources_t sources, idevice_connection_t *connection)
cdef class FileRelayError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
FILE_RELAY_E_SUCCESS: "Success",
FILE_RELAY_E_INVALID_ARG: "Invalid argument",
FILE_RELAY_E_PLIST_ERROR: "Property list error",
FILE_RELAY_E_MUX_ERROR: "MUX error",
FILE_RELAY_E_INVALID_SOURCE: "Invalid source",
FILE_RELAY_E_STAGING_EMPTY: "Staging empty",
FILE_RELAY_E_PERMISSION_DENIED: "Permission denied",
FILE_RELAY_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
from libc.stdlib cimport *
cdef class FileRelayClient(PropertyListService):
__service_name__ = "com.apple.mobile.file_relay"
cdef file_relay_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(file_relay_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef file_relay_error_t err
if self._c_client is not NULL:
err = file_relay_client_free(self._c_client)
self.handle_error(err)
cpdef iDeviceConnection request_sources(self, list sources):
cdef:
file_relay_error_t err
Py_ssize_t count = len(sources)
char** c_sources = <char**>malloc(sizeof(char*) * (count + 1))
iDeviceConnection conn = iDeviceConnection.__new__(iDeviceConnection)
for i, value in enumerate(sources):
c_sources[i] = value
c_sources[count] = NULL
err = file_relay_request_sources(self._c_client, <const_sources_t>c_sources, &conn._c_connection)
free(c_sources)
self.handle_error(err)
return conn
cdef inline BaseError _error(self, int16_t ret):
return FileRelayError(ret)

View File

@@ -1,60 +0,0 @@
cdef extern from "libimobiledevice/heartbeat.h":
cdef struct heartbeat_client_private:
pass
ctypedef heartbeat_client_private *heartbeat_client_t
ctypedef enum heartbeat_error_t:
HEARTBEAT_E_SUCCESS = 0
HEARTBEAT_E_INVALID_ARG = -1
HEARTBEAT_E_PLIST_ERROR = -2
HEARTBEAT_E_MUX_ERROR = -3
HEARTBEAT_E_SSL_ERROR = -4
HEARTBEAT_E_NOT_ENOUGH_DATA = -5
HEARTBEAT_E_TIMEOUT = -6
HEARTBEAT_E_UNKNOWN_ERROR = -256
heartbeat_error_t heartbeat_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, heartbeat_client_t * client)
heartbeat_error_t heartbeat_client_free(heartbeat_client_t client)
heartbeat_error_t heartbeat_send(heartbeat_client_t client, plist.plist_t plist)
heartbeat_error_t heartbeat_receive(heartbeat_client_t client, plist.plist_t * plist)
heartbeat_error_t heartbeat_receive_with_timeout(heartbeat_client_t client, plist.plist_t * plist, uint32_t timeout_ms)
cdef class HeartbeatError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
HEARTBEAT_E_SUCCESS: "Success",
HEARTBEAT_E_INVALID_ARG: "Invalid argument",
HEARTBEAT_E_PLIST_ERROR: "Property list error",
HEARTBEAT_E_MUX_ERROR: "MUX error",
HEARTBEAT_E_SSL_ERROR: "SSL Error",
HEARTBEAT_E_NOT_ENOUGH_DATA: 'Not enough data',
HEARTBEAT_E_TIMEOUT: 'Connection timeout',
HEARTBEAT_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class HeartbeatClient(PropertyListService):
__service_name__ = "com.apple.heartbeat"
cdef heartbeat_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(heartbeat_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef heartbeat_error_t err
if self._c_client is not NULL:
err = heartbeat_client_free(self._c_client)
self.handle_error(err)
cdef inline int16_t _send(self, plist.plist_t node):
return heartbeat_send(self._c_client, node)
cdef inline int16_t _receive(self, plist.plist_t* node):
return heartbeat_receive(self._c_client, node)
cdef inline int16_t _receive_with_timeout(self, plist.plist_t* node, int timeout_ms):
return heartbeat_receive_with_timeout(self._c_client, node, timeout_ms)
cdef inline BaseError _error(self, int16_t ret):
return HeartbeatError(ret)

View File

@@ -1,84 +0,0 @@
cdef extern from "libimobiledevice/house_arrest.h":
cdef struct house_arrest_client_private:
pass
ctypedef house_arrest_client_private *house_arrest_client_t
ctypedef enum house_arrest_error_t:
HOUSE_ARREST_E_SUCCESS = 0
HOUSE_ARREST_E_INVALID_ARG = -1
HOUSE_ARREST_E_PLIST_ERROR = -2
HOUSE_ARREST_E_CONN_FAILED = -3
HOUSE_ARREST_E_INVALID_MODE = -4
HOUSE_ARREST_E_UNKNOWN_ERROR = -256
house_arrest_error_t house_arrest_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, house_arrest_client_t * client)
house_arrest_error_t house_arrest_client_free(house_arrest_client_t client)
house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist.plist_t dict)
house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, char *command, char *appid)
house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist.plist_t *dict)
afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client)
cdef class HouseArrestError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
HOUSE_ARREST_E_SUCCESS: "Success",
HOUSE_ARREST_E_INVALID_ARG: "Invalid argument",
HOUSE_ARREST_E_PLIST_ERROR: "Property list error",
HOUSE_ARREST_E_CONN_FAILED: "Connection failed",
HOUSE_ARREST_E_INVALID_MODE: "Invalid mode",
HOUSE_ARREST_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class HouseArrestClient(PropertyListService):
__service_name__ = "com.apple.mobile.house_arrest"
cdef house_arrest_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(house_arrest_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef house_arrest_error_t err
if self._c_client is not NULL:
err = house_arrest_client_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return HouseArrestError(ret)
cpdef send_request(self, plist.Node message):
self.handle_error(house_arrest_send_request(self._c_client, message._c_node))
cpdef send_command(self, bytes command, bytes appid):
self.handle_error(house_arrest_send_command(self._c_client, command, appid))
cpdef plist.Node get_result(self):
cdef:
plist.plist_t c_node = NULL
house_arrest_error_t err
err = house_arrest_get_result(self._c_client, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef AfcClient to_afc_client(self):
cdef:
afc_client_t c_afc_client = NULL
AfcClient result
afc_error_t err
err = afc_client_new_from_house_arrest_client(self._c_client, &c_afc_client)
try:
result = AfcClient.__new__(AfcClient)
result._c_client = c_afc_client
result.handle_error(err)
return result
except BaseError, e:
if c_afc_client != NULL:
afc_client_free(c_afc_client);
raise

View File

@@ -1,107 +0,0 @@
cimport plist
from libc.stdint cimport *
cdef extern from "pyerrors.h":
ctypedef class __builtin__.Exception [object PyBaseExceptionObject]:
pass
cdef class BaseError(Exception):
cdef dict _lookup_table
cdef int16_t _c_errcode
cdef class Base:
cdef inline int handle_error(self, int16_t ret) except -1
cdef BaseError _error(self, int16_t ret)
cdef class iDeviceError(BaseError): pass
cdef extern from "libimobiledevice/libimobiledevice.h":
cdef struct idevice_private:
pass
ctypedef idevice_private* idevice_t
cdef struct idevice_connection_private:
pass
ctypedef idevice_connection_private* idevice_connection_t
cdef enum idevice_connection_type:
CONNECTION_USBMUXD = 1
CONNECTION_NETWORK
cdef enum idevice_event_type:
IDEVICE_DEVICE_ADD = 1
IDEVICE_DEVICE_REMOVE
IDEVICE_DEVICE_PAIRED
ctypedef struct idevice_event_t:
idevice_event_type event
char *udid
idevice_connection_type conn_type
ctypedef idevice_event_t* const_idevice_event_t "const idevice_event_t*"
cdef class iDeviceEvent:
cdef const_idevice_event_t _c_event
cdef class iDeviceConnection(Base):
cdef idevice_connection_t _c_connection
cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout)
cpdef bytes receive(self, max_len)
cpdef disconnect(self)
cdef class iDevice(Base):
cdef idevice_t _c_dev
cpdef iDeviceConnection connect(self, uint16_t port)
cdef class BaseService(Base):
pass
cdef class PropertyListService(BaseService):
cpdef send(self, plist.Node node)
cpdef object receive(self)
cpdef object receive_with_timeout(self, int timeout_ms)
cdef int16_t _send(self, plist.plist_t node)
cdef int16_t _receive(self, plist.plist_t* c_node)
cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms)
cdef extern from "libimobiledevice/lockdown.h":
cdef struct lockdownd_client_private:
pass
ctypedef lockdownd_client_private *lockdownd_client_t
cdef struct lockdownd_pair_record:
char *device_certificate
char *host_certificate
char *host_id
char *root_certificate
ctypedef lockdownd_pair_record *lockdownd_pair_record_t
cdef struct lockdownd_service_descriptor:
uint16_t port
uint8_t ssl_enabled
ctypedef lockdownd_service_descriptor *lockdownd_service_descriptor_t
cdef class LockdownError(BaseError): pass
cdef class LockdownPairRecord:
cdef lockdownd_pair_record_t _c_record
cdef class LockdownServiceDescriptor(Base):
cdef lockdownd_service_descriptor_t _c_service_descriptor
cdef class LockdownClient(PropertyListService):
cdef lockdownd_client_t _c_client
cdef readonly iDevice device
cpdef bytes query_type(self)
cpdef plist.Node get_value(self, bytes domain=*, bytes key=*)
cpdef set_value(self, bytes domain, bytes key, object value)
cpdef remove_value(self, bytes domain, bytes key)
cpdef object start_service(self, object service)
cpdef object get_service_client(self, object service_class)
cpdef tuple start_session(self, bytes host_id)
cpdef stop_session(self, bytes session_id)
cpdef pair(self, object pair_record=*)
cpdef validate_pair(self, object pair_record=*)
cpdef unpair(self, object pair_record=*)
cpdef activate(self, plist.Node activation_record)
cpdef deactivate(self)
cpdef enter_recovery(self)
cpdef goodbye(self)
cpdef list get_sync_data_classes(self)

View File

@@ -1,294 +0,0 @@
cdef class BaseError(Exception):
def __cinit__(self, int16_t errcode):
self._c_errcode = errcode
def __nonzero__(self):
return self._c_errcode != 0
property message:
def __get__(self):
if self._c_errcode in self._lookup_table:
return self._lookup_table[self._c_errcode]
else:
return "Unknown error ({0})".format(self._c_errcode)
property code:
def __get__(self):
return self._c_errcode
def __str__(self):
return '%s (%s)' % (self.message, self.code)
def __repr__(self):
return self.__str__()
cdef class Base:
cdef inline int handle_error(self, int16_t ret) except -1:
if ret == 0:
return 0
cdef BaseError err = self._error(ret)
raise err
cdef BaseError _error(self, int16_t ret): pass
cdef extern from "libimobiledevice/libimobiledevice.h":
ctypedef enum idevice_error_t:
IDEVICE_E_SUCCESS = 0
IDEVICE_E_INVALID_ARG = -1
IDEVICE_E_UNKNOWN_ERROR = -2
IDEVICE_E_NO_DEVICE = -3
IDEVICE_E_NOT_ENOUGH_DATA = -4
IDEVICE_E_SSL_ERROR = -6
IDEVICE_E_TIMEOUT = -7
cdef enum idevice_options:
IDEVICE_LOOKUP_USBMUX = 1 << 1
IDEVICE_LOOKUP_NETWORK = 1 << 2
IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3
ctypedef void (*idevice_event_cb_t) (const_idevice_event_t event, void *user_data)
cdef extern idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data)
cdef extern idevice_error_t idevice_event_unsubscribe()
idevice_error_t idevice_get_device_list(char ***devices, int *count)
idevice_error_t idevice_device_list_free(char **devices)
void idevice_set_debug_level(int level)
idevice_error_t idevice_new(idevice_t *device, char *udid)
idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, idevice_options options);
idevice_error_t idevice_free(idevice_t device)
idevice_error_t idevice_get_udid(idevice_t device, char** udid)
idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle)
idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection)
idevice_error_t idevice_disconnect(idevice_connection_t connection)
idevice_error_t idevice_connection_send(idevice_connection_t connection, char *data, uint32_t len, uint32_t *sent_bytes)
idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes)
cdef class iDeviceError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
IDEVICE_E_SUCCESS: 'Success',
IDEVICE_E_INVALID_ARG: 'Invalid argument',
IDEVICE_E_UNKNOWN_ERROR: 'Unknown error',
IDEVICE_E_NO_DEVICE: 'No device',
IDEVICE_E_NOT_ENOUGH_DATA: 'Not enough data',
IDEVICE_E_SSL_ERROR: 'SSL Error',
IDEVICE_E_TIMEOUT: 'Connection timeout'
}
BaseError.__init__(self, *args, **kwargs)
def set_debug_level(int level):
idevice_set_debug_level(level)
cdef class iDeviceEvent:
def __init__(self, *args, **kwargs):
raise TypeError("iDeviceEvent cannot be instantiated")
def __str__(self):
return 'iDeviceEvent: %s (%s)' % (self.event == IDEVICE_DEVICE_ADD and 'Add' or 'Remove', self.udid)
property event:
def __get__(self):
return self._c_event.event
property udid:
def __get__(self):
return self._c_event.udid
property conn_type:
def __get__(self):
return self._c_event.conn_type
cdef void idevice_event_cb(const_idevice_event_t c_event, void *user_data) with gil:
cdef iDeviceEvent event = iDeviceEvent.__new__(iDeviceEvent)
event._c_event = c_event
(<object>user_data)(event)
def event_subscribe(object callback):
cdef iDeviceError err = iDeviceError(idevice_event_subscribe(idevice_event_cb, <void*>callback))
if err: raise err
def event_unsubscribe():
cdef iDeviceError err = iDeviceError(idevice_event_unsubscribe())
if err: raise err
def get_device_list():
cdef:
char** devices = NULL
int count
list result
bytes device
iDeviceError err = iDeviceError(idevice_get_device_list(&devices, &count))
if err:
if devices != NULL:
idevice_device_list_free(devices)
raise err
result = []
for i from 0 <= i < count:
device = devices[i]
result.append(device)
err = iDeviceError(idevice_device_list_free(devices))
if err: raise err
return result
cdef class iDeviceConnection(Base):
def __init__(self, *args, **kwargs):
raise TypeError("iDeviceConnection cannot be instantiated. Please use iDevice.connect()")
cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout):
cdef:
uint32_t bytes_received
char* c_data = <char *>malloc(max_len)
bytes result
try:
self.handle_error(idevice_connection_receive_timeout(self._c_connection, c_data, max_len, &bytes_received, timeout))
result = c_data[:bytes_received]
return result
except BaseError, e:
raise
finally:
free(c_data)
cpdef bytes receive(self, max_len):
cdef:
uint32_t bytes_received
char* c_data = <char *>malloc(max_len)
bytes result
try:
self.handle_error(idevice_connection_receive(self._c_connection, c_data, max_len, &bytes_received))
result = c_data[:bytes_received]
return result
except BaseError, e:
raise
finally:
free(c_data)
cpdef disconnect(self):
cdef idevice_error_t err
err = idevice_disconnect(self._c_connection)
self.handle_error(err)
cdef BaseError _error(self, int16_t ret):
return iDeviceError(ret)
from libc.stdlib cimport *
cdef class iDevice(Base):
def __cinit__(self, object udid=None, *args, **kwargs):
cdef char* c_udid = NULL
if isinstance(udid, (str, bytes)):
c_udid = <bytes>udid
elif udid is not None:
raise TypeError("iDevice's constructor takes a string or None as the udid argument")
self.handle_error(idevice_new(&self._c_dev, c_udid))
def __dealloc__(self):
if self._c_dev is not NULL:
self.handle_error(idevice_free(self._c_dev))
cdef BaseError _error(self, int16_t ret):
return iDeviceError(ret)
cpdef iDeviceConnection connect(self, uint16_t port):
cdef:
idevice_error_t err
idevice_connection_t c_conn = NULL
iDeviceConnection conn
err = idevice_connect(self._c_dev, port, &c_conn)
try:
self.handle_error(err)
conn = iDeviceConnection.__new__(iDeviceConnection)
conn._c_connection = c_conn
return conn
except Exception, e:
if c_conn != NULL:
idevice_disconnect(c_conn)
property udid:
def __get__(self):
cdef:
char* udid
idevice_error_t err
err = idevice_get_udid(self._c_dev, &udid)
try:
self.handle_error(err)
return udid
except Exception, e:
if udid != NULL:
free(udid)
property handle:
def __get__(self):
cdef uint32_t handle
self.handle_error(idevice_get_handle(self._c_dev, &handle))
return handle
cdef extern from *:
ctypedef char* const_char_ptr "const char*"
cdef class BaseService(Base):
__service_name__ = None
cdef class PropertyListService(BaseService):
cpdef send(self, plist.Node node):
self.handle_error(self._send(node._c_node))
cpdef object receive(self):
cdef:
plist.plist_t c_node = NULL
int16_t err
err = self._receive(&c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef object receive_with_timeout(self, int timeout_ms):
cdef:
plist.plist_t c_node = NULL
int16_t err
err = self._receive_with_timeout(&c_node, timeout_ms)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cdef int16_t _send(self, plist.plist_t node):
raise NotImplementedError("send is not implemented")
cdef int16_t _receive(self, plist.plist_t* c_node):
raise NotImplementedError("receive is not implemented")
cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms):
raise NotImplementedError("receive_with_timeout is not implemented")
cdef class DeviceLinkService(PropertyListService):
pass
include "lockdown.pxi"
include "mobilesync.pxi"
include "notification_proxy.pxi"
include "sbservices.pxi"
include "mobilebackup.pxi"
include "mobilebackup2.pxi"
include "afc.pxi"
include "file_relay.pxi"
include "screenshotr.pxi"
include "installation_proxy.pxi"
include "mobile_image_mounter.pxi"
include "webinspector.pxi"
include "heartbeat.pxi"
include "diagnostics_relay.pxi"
include "misagent.pxi"
include "house_arrest.pxi"
include "restore.pxi"
include "debugserver.pxi"

View File

@@ -1,304 +0,0 @@
cdef extern from "libimobiledevice/installation_proxy.h":
cdef struct instproxy_client_private:
pass
ctypedef instproxy_client_private *instproxy_client_t
ctypedef void (*instproxy_status_cb_t) (plist.plist_t command, plist.plist_t status, void *user_data)
ctypedef enum instproxy_error_t:
INSTPROXY_E_SUCCESS = 0
INSTPROXY_E_INVALID_ARG = -1
INSTPROXY_E_PLIST_ERROR = -2
INSTPROXY_E_CONN_FAILED = -3
INSTPROXY_E_OP_IN_PROGRESS = -4
INSTPROXY_E_OP_FAILED = -5
INSTPROXY_E_UNKNOWN_ERROR = -256
instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, instproxy_client_t *client)
instproxy_error_t instproxy_client_free(instproxy_client_t client)
instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path)
instproxy_error_t instproxy_browse(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result)
instproxy_error_t instproxy_install(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
instproxy_error_t instproxy_upgrade(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
instproxy_error_t instproxy_uninstall(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result)
instproxy_error_t instproxy_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
instproxy_error_t instproxy_restore(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
instproxy_error_t instproxy_remove_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
cdef void instproxy_notify_cb(plist.plist_t command, plist.plist_t status, void *py_callback) with gil:
(<object>py_callback)(plist.plist_t_to_node(command, False), plist.plist_t_to_node(status, False))
cdef class InstallationProxyError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
INSTPROXY_E_SUCCESS: "Success",
INSTPROXY_E_INVALID_ARG: "Invalid argument",
INSTPROXY_E_PLIST_ERROR: "Property list error",
INSTPROXY_E_CONN_FAILED: "Connection failed",
INSTPROXY_E_OP_IN_PROGRESS: "Operation in progress",
INSTPROXY_E_OP_FAILED: "Operation failed",
INSTPROXY_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class InstallationProxyClient(PropertyListService):
__service_name__ = "com.apple.mobile.installation_proxy"
cdef instproxy_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
cdef:
iDevice dev = device
instproxy_error_t err
err = instproxy_client_new(dev._c_dev, descriptor._c_service_descriptor, &self._c_client)
self.handle_error(err)
def __dealloc__(self):
cdef instproxy_error_t err
if self._c_client is not NULL:
err = instproxy_client_free(self._c_client)
self.handle_error(err)
cpdef get_path_for_bundle_identifier(self, bytes bundle_id):
cdef:
char* c_bundle_id = bundle_id
char* c_path = NULL
bytes result
try:
self.handle_error(instproxy_client_get_path_for_bundle_identifier(self._c_client, c_bundle_id, &c_path))
if c_path != NULL:
result = c_path
return result
else:
return None
except BaseError, e:
raise
finally:
free(c_path)
cpdef plist.Node browse(self, object client_options):
cdef:
plist.Node options
plist.plist_t c_options
plist.plist_t c_result = NULL
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
err = instproxy_browse(self._c_client, c_options, &c_result)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_result)
except Exception, e:
if c_result != NULL:
plist.plist_free(c_result)
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef install(self, bytes pkg_path, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_install(self._c_client, pkg_path, c_options, NULL, NULL)
else:
err = instproxy_install(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef upgrade(self, bytes pkg_path, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_upgrade(self._c_client, pkg_path, c_options, NULL, NULL)
else:
err = instproxy_upgrade(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef uninstall(self, bytes appid, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
instproxy_error_t err
bint free_options = False
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_uninstall(self._c_client, appid, c_options, NULL, NULL)
else:
err = instproxy_uninstall(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef plist.Node lookup_archives(self, object client_options):
cdef:
plist.Node options
plist.plist_t c_options
plist.plist_t c_node = NULL
instproxy_error_t err
bint free_options = False
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
err = instproxy_lookup_archives(self._c_client, c_options, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except Exception, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef archive(self, bytes appid, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_archive(self._c_client, appid, c_options, NULL, NULL)
else:
err = instproxy_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef restore(self, bytes appid, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_restore(self._c_client, appid, c_options, NULL, NULL)
else:
err = instproxy_restore(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cpdef remove_archive(self, bytes appid, object client_options, object callback=None):
cdef:
plist.Node options
plist.plist_t c_options
bint free_options = False
instproxy_error_t err
if isinstance(client_options, plist.Dict):
options = client_options
c_options = options._c_node
elif isinstance(client_options, dict):
c_options = plist.native_to_plist_t(client_options)
free_options = True
else:
raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
if callback is None:
err = instproxy_remove_archive(self._c_client, appid, c_options, NULL, NULL)
else:
err = instproxy_remove_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
try:
self.handle_error(err)
except Exception, e:
raise
finally:
if free_options:
plist.plist_free(c_options)
cdef inline BaseError _error(self, int16_t ret):
return InstallationProxyError(ret)

View File

@@ -1,341 +0,0 @@
cdef extern from "libimobiledevice/lockdown.h":
ctypedef enum lockdownd_error_t:
LOCKDOWN_E_SUCCESS
LOCKDOWN_E_INVALID_ARG
LOCKDOWN_E_INVALID_CONF
LOCKDOWN_E_PLIST_ERROR
LOCKDOWN_E_PAIRING_FAILED
LOCKDOWN_E_SSL_ERROR
LOCKDOWN_E_DICT_ERROR
LOCKDOWN_E_RECEIVE_TIMEOUT
LOCKDOWN_E_SET_VALUE_PROHIBITED
LOCKDOWN_E_GET_VALUE_PROHIBITED
LOCKDOWN_E_MUX_ERROR
LOCKDOWN_E_NO_RUNNING_SESSION
LOCKDOWN_E_INVALID_RESPONSE
LOCKDOWN_E_MISSING_KEY
LOCKDOWN_E_MISSING_VALUE
LOCKDOWN_E_GET_PROHIBITED
LOCKDOWN_E_SET_PROHIBITED
LOCKDOWN_E_REMOVE_PROHIBITED
LOCKDOWN_E_IMMUTABLE_VALUE
LOCKDOWN_E_PASSWORD_PROTECTED
LOCKDOWN_E_USER_DENIED_PAIRING
LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING
LOCKDOWN_E_MISSING_HOST_ID
LOCKDOWN_E_INVALID_HOST_ID
LOCKDOWN_E_SESSION_ACTIVE
LOCKDOWN_E_SESSION_INACTIVE
LOCKDOWN_E_MISSING_SESSION_ID
LOCKDOWN_E_INVALID_SESSION_ID
LOCKDOWN_E_MISSING_SERVICE
LOCKDOWN_E_INVALID_SERVICE
LOCKDOWN_E_SERVICE_LIMIT
LOCKDOWN_E_MISSING_PAIR_RECORD
LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED
LOCKDOWN_E_INVALID_PAIR_RECORD
LOCKDOWN_E_INVALID_ACTIVATION_RECORD
LOCKDOWN_E_MISSING_ACTIVATION_RECORD
LOCKDOWN_E_SERVICE_PROHIBITED
LOCKDOWN_E_ESCROW_LOCKED
LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION
LOCKDOWN_E_FMIP_PROTECTED
LOCKDOWN_E_MC_PROTECTED
LOCKDOWN_E_MC_CHALLENGE_REQUIRED
LOCKDOWN_E_UNKNOWN_ERROR
lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label)
lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label)
lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp)
lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value)
lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value)
lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key)
lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *identifier, lockdownd_service_descriptor_t *service)
lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled)
lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id)
lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist)
lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist)
lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record)
lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count)
lockdownd_error_t lockdownd_data_classes_free(char **classes)
lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service)
cdef class LockdownError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
LOCKDOWN_E_SUCCESS: "Success",
LOCKDOWN_E_INVALID_ARG: "Invalid argument",
LOCKDOWN_E_INVALID_CONF: "Invalid configuration",
LOCKDOWN_E_PLIST_ERROR: "Property list error",
LOCKDOWN_E_PAIRING_FAILED: "Pairing failed",
LOCKDOWN_E_SSL_ERROR: "SSL error",
LOCKDOWN_E_DICT_ERROR: "Dictionary error",
LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout",
LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error",
LOCKDOWN_E_NO_RUNNING_SESSION: "No running session",
LOCKDOWN_E_INVALID_RESPONSE: "Invalid response",
LOCKDOWN_E_MISSING_KEY: "Missing key",
LOCKDOWN_E_MISSING_VALUE: "Missing value",
LOCKDOWN_E_GET_PROHIBITED: "Get value prohibited",
LOCKDOWN_E_SET_PROHIBITED: "Set value prohibited",
LOCKDOWN_E_REMOVE_PROHIBITED: "Remove value prohibited",
LOCKDOWN_E_IMMUTABLE_VALUE: "Immutable value",
LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected",
LOCKDOWN_E_USER_DENIED_PAIRING: "User denied pairing",
LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: "Pairing dialog response pending",
LOCKDOWN_E_MISSING_HOST_ID: "Missing host ID",
LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID",
LOCKDOWN_E_SESSION_ACTIVE: "Session active",
LOCKDOWN_E_SESSION_INACTIVE: "Session inactive",
LOCKDOWN_E_MISSING_SESSION_ID: "Missing session ID",
LOCKDOWN_E_INVALID_SESSION_ID: "Invalid session ID",
LOCKDOWN_E_MISSING_SERVICE: "Missing service",
LOCKDOWN_E_INVALID_SERVICE: "Invalid service",
LOCKDOWN_E_SERVICE_LIMIT: "Service limit reached",
LOCKDOWN_E_MISSING_PAIR_RECORD: "Missing pair record",
LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED: "Saving pair record failed",
LOCKDOWN_E_INVALID_PAIR_RECORD: "Invalid pair record",
LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record",
LOCKDOWN_E_MISSING_ACTIVATION_RECORD: "Missing activation record",
LOCKDOWN_E_SERVICE_PROHIBITED: "Service prohibited",
LOCKDOWN_E_ESCROW_LOCKED: "Escrow locked",
LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: "Pairing prohibited over this connection",
LOCKDOWN_E_FMIP_PROTECTED: "Find My iPhone/iPod/iPad protected",
LOCKDOWN_E_MC_PROTECTED: "MC protected",
LOCKDOWN_E_MC_CHALLENGE_REQUIRED: "MC challenge required",
LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class LockdownPairRecord:
#def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs):
property device_certificate:
def __get__(self):
cdef bytes result = self._c_record.device_certificate
return result
property host_certificate:
def __get__(self):
cdef bytes result = self._c_record.host_certificate
return result
property host_id:
def __get__(self):
cdef bytes result = self._c_record.host_id
return result
property root_certificate:
def __get__(self):
cdef bytes result = self._c_record.root_certificate
return result
cdef class LockdownServiceDescriptor(Base):
#def __cinit__(self, uint16_t port, uint8_t ssl_enabled, *args, **kwargs):
def __dealloc__(self):
cdef lockdownd_error_t err
if self._c_service_descriptor is not NULL:
err = lockdownd_service_descriptor_free(self._c_service_descriptor)
self._c_service_descriptor = NULL
self.handle_error(err)
property port:
def __get__(self):
return self._c_service_descriptor.port
property ssl_enabled:
def __get__(self):
return self._c_service_descriptor.ssl_enabled
cdef class LockdownClient(PropertyListService):
def __cinit__(self, iDevice device not None, bytes label=b'', bint handshake=True, *args, **kwargs):
cdef:
lockdownd_error_t err
char* c_label = NULL
if label:
c_label = label
if handshake:
err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label)
else:
err = lockdownd_client_new(device._c_dev, &self._c_client, c_label)
self.handle_error(err)
self.device = device
def __dealloc__(self):
cdef lockdownd_error_t err
if self._c_client is not NULL:
err = lockdownd_client_free(self._c_client)
self.handle_error(err)
cpdef bytes query_type(self):
cdef:
lockdownd_error_t err
char* c_type = NULL
bytes result
err = lockdownd_query_type(self._c_client, &c_type)
try:
self.handle_error(err)
result = c_type
return result
except BaseError, e:
raise
finally:
if c_type != NULL:
free(c_type)
cpdef plist.Node get_value(self, bytes domain=None, bytes key=None):
cdef:
lockdownd_error_t err
plist.plist_t c_node = NULL
char* c_domain = NULL
char* c_key = NULL
if domain is not None:
c_domain = domain
if key is not None:
c_key = key
err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef set_value(self, bytes domain, bytes key, object value):
cdef plist.plist_t c_node = plist.native_to_plist_t(value)
try:
self.handle_error(lockdownd_set_value(self._c_client, domain, key, c_node))
except BaseError, e:
raise
finally:
if c_node != NULL:
plist.plist_free(c_node)
cpdef remove_value(self, bytes domain, bytes key):
self.handle_error(lockdownd_remove_value(self._c_client, domain, key))
cpdef object start_service(self, object service):
cdef:
char* c_service_name = NULL
lockdownd_service_descriptor_t c_descriptor = NULL
LockdownServiceDescriptor result
if issubclass(service, BaseService) and \
service.__service_name__ is not None \
and isinstance(service.__service_name__, (str, bytes)):
c_service_name = <bytes>service.__service_name__
elif isinstance(service, (str, bytes)):
c_service_name = <bytes>service
else:
raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument")
try:
self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &c_descriptor))
result = LockdownServiceDescriptor.__new__(LockdownServiceDescriptor)
result._c_service_descriptor = c_descriptor
return result
except BaseError, e:
raise
cpdef object get_service_client(self, object service_class):
cdef:
LockdownServiceDescriptor descriptor
if not hasattr(service_class, '__service_name__') and \
not service_class.__service_name__ is not None \
and not isinstance(service_class.__service_name__, (str, bytes)):
raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument")
descriptor = self.start_service(service_class)
return service_class(self.device, descriptor)
cpdef tuple start_session(self, bytes host_id):
cdef:
lockdownd_error_t err
char* c_session_id = NULL
bint ssl_enabled
bytes session_id
err = lockdownd_start_session(self._c_client, host_id, &c_session_id, <int *>&ssl_enabled)
try:
self.handle_error(err)
session_id = c_session_id
return (session_id, ssl_enabled)
except BaseError, e:
raise
finally:
if c_session_id != NULL:
free(c_session_id)
cpdef stop_session(self, bytes session_id):
self.handle_error(lockdownd_stop_session(self._c_client, session_id))
cpdef pair(self, object pair_record=None):
cdef lockdownd_pair_record_t c_pair_record = NULL
if pair_record is not None:
c_pair_record = (<LockdownPairRecord>pair_record)._c_record
self.handle_error(lockdownd_pair(self._c_client, c_pair_record))
cpdef validate_pair(self, object pair_record=None):
cdef lockdownd_pair_record_t c_pair_record = NULL
if pair_record is not None:
c_pair_record = (<LockdownPairRecord>pair_record)._c_record
self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record))
cpdef unpair(self, object pair_record=None):
cdef lockdownd_pair_record_t c_pair_record = NULL
if pair_record is not None:
c_pair_record = (<LockdownPairRecord>pair_record)._c_record
self.handle_error(lockdownd_unpair(self._c_client, c_pair_record))
cpdef activate(self, plist.Node activation_record):
self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node))
cpdef deactivate(self):
self.handle_error(lockdownd_deactivate(self._c_client))
cpdef enter_recovery(self):
self.handle_error(lockdownd_enter_recovery(self._c_client))
cpdef goodbye(self):
self.handle_error(lockdownd_goodbye(self._c_client))
cpdef list get_sync_data_classes(self):
cdef:
char **classes = NULL
int count = 0
list result = []
bytes data_class
try:
self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count))
for i from 0 <= i < count:
data_class = classes[i]
result.append(data_class)
return result
except Exception, e:
raise
finally:
if classes != NULL:
lockdownd_data_classes_free(classes)
cdef inline int16_t _send(self, plist.plist_t node):
return lockdownd_send(self._c_client, node)
cdef inline int16_t _receive(self, plist.plist_t* node):
return lockdownd_receive(self._c_client, node)
cdef inline BaseError _error(self, int16_t ret):
return LockdownError(ret)

View File

@@ -1,74 +0,0 @@
cdef extern from "libimobiledevice/misagent.h":
cdef struct misagent_client_private:
pass
ctypedef misagent_client_private *misagent_client_t
ctypedef enum misagent_error_t:
MISAGENT_E_SUCCESS = 0
MISAGENT_E_INVALID_ARG = -1
MISAGENT_E_PLIST_ERROR = -2
MISAGENT_E_CONN_FAILED = -3
MISAGENT_E_REQUEST_FAILED = -4
MISAGENT_E_UNKNOWN_ERROR = -256
misagent_error_t misagent_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, misagent_client_t * client)
misagent_error_t misagent_client_free(misagent_client_t client)
misagent_error_t misagent_install(misagent_client_t client, plist.plist_t profile)
misagent_error_t misagent_copy(misagent_client_t client, plist.plist_t* profiles)
misagent_error_t misagent_remove(misagent_client_t client, char* profileID)
int misagent_get_status_code(misagent_client_t client)
cdef class MisagentError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
MISAGENT_E_SUCCESS: "Success",
MISAGENT_E_INVALID_ARG: "Invalid argument",
MISAGENT_E_PLIST_ERROR: "Property list error",
MISAGENT_E_CONN_FAILED: "Connection failed",
MISAGENT_E_REQUEST_FAILED: "Request failed",
MISAGENT_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class MisagentClient(PropertyListService):
__service_name__ = "com.apple.misagent"
cdef misagent_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(misagent_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef misagent_error_t err
if self._c_client is not NULL:
err = misagent_client_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return MisagentError(ret)
cpdef install(self, plist.Node profile):
cdef misagent_error_t err
err = misagent_install(self._c_client, profile._c_node)
self.handle_error(err)
cpdef plist.Node copy(self):
cdef:
plist.plist_t c_node = NULL
misagent_error_t err
err = misagent_copy(self._c_client, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef remove(self, bytes profile_id):
cdef misagent_error_t err
err = misagent_remove(self._c_client, profile_id)
self.handle_error(err)
cpdef int get_status_code(self):
return misagent_get_status_code(self._c_client)

View File

@@ -1,78 +0,0 @@
cdef extern from "libimobiledevice/mobile_image_mounter.h":
cdef struct mobile_image_mounter_client_private:
pass
ctypedef mobile_image_mounter_client_private *mobile_image_mounter_client_t
ctypedef enum mobile_image_mounter_error_t:
MOBILE_IMAGE_MOUNTER_E_SUCCESS = 0
MOBILE_IMAGE_MOUNTER_E_INVALID_ARG = -1
MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR = -2
MOBILE_IMAGE_MOUNTER_E_CONN_FAILED = -3
MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR = -256
mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobile_image_mounter_client_t *client)
mobile_image_mounter_error_t mobile_image_mounter_free(mobile_image_mounter_client_t client)
mobile_image_mounter_error_t mobile_image_mounter_lookup_image(mobile_image_mounter_client_t client, char *image_type, plist.plist_t *result)
mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, char *image_path, char *image_signature, uint16_t signature_length, char *image_type, plist.plist_t *result)
mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client)
cdef class MobileImageMounterError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
MOBILE_IMAGE_MOUNTER_E_SUCCESS: "Success",
MOBILE_IMAGE_MOUNTER_E_INVALID_ARG: "Invalid argument",
MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR: "Property list error",
MOBILE_IMAGE_MOUNTER_E_CONN_FAILED: "Connection failed",
MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class MobileImageMounterClient(PropertyListService):
__service_name__ = "com.apple.mobile.mobile_image_mounter"
cdef mobile_image_mounter_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(mobile_image_mounter_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef mobile_image_mounter_error_t err
if self._c_client is not NULL:
err = mobile_image_mounter_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return MobileImageMounterError(ret)
cpdef plist.Node lookup_image(self, bytes image_type):
cdef:
plist.plist_t c_node = NULL
mobile_image_mounter_error_t err
err = mobile_image_mounter_lookup_image(self._c_client, image_type, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except Exception, e:
if c_node != NULL:
plist.plist_free(c_node)
cpdef plist.Node mount_image(self, bytes image_path, bytes image_signature, bytes image_type):
cdef:
plist.plist_t c_node = NULL
mobile_image_mounter_error_t err
err = mobile_image_mounter_mount_image(self._c_client, image_path, image_signature, len(image_signature),
image_type, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except Exception, e:
if c_node != NULL:
plist.plist_free(c_node)
cpdef hangup(self):
cdef mobile_image_mounter_error_t err
err = mobile_image_mounter_hangup(self._c_client)
self.handle_error(err)

View File

@@ -1,110 +0,0 @@
cdef extern from "libimobiledevice/mobilebackup.h":
cdef struct mobilebackup_client_private:
pass
ctypedef mobilebackup_client_private *mobilebackup_client_t
ctypedef enum mobilebackup_error_t:
MOBILEBACKUP_E_SUCCESS = 0
MOBILEBACKUP_E_INVALID_ARG = -1
MOBILEBACKUP_E_PLIST_ERROR = -2
MOBILEBACKUP_E_MUX_ERROR = -3
MOBILEBACKUP_E_SSL_ERROR = -4
MOBILEBACKUP_E_RECEIVE_TIMEOUT = -5
MOBILEBACKUP_E_BAD_VERSION = -6
MOBILEBACKUP_E_REPLY_NOT_OK = -7
MOBILEBACKUP_E_UNKNOWN_ERROR = -256
ctypedef enum mobilebackup_flags_t:
MB_RESTORE_NOTIFY_SPRINGBOARD = (1 << 0)
MB_RESTORE_PRESERVE_SETTINGS = (1 << 1)
MB_RESTORE_PRESERVE_CAMERA_ROLL = (1 << 2)
mobilebackup_error_t mobilebackup_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobilebackup_client_t * client)
mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client)
mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist.plist_t *plist)
mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist.plist_t plist)
mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist.plist_t backup_manifest, char *base_path, char *proto_version)
mobilebackup_error_t mobilebackup_send_backup_file_received(mobilebackup_client_t client)
mobilebackup_error_t mobilebackup_request_restore(mobilebackup_client_t client, plist.plist_t backup_manifest, mobilebackup_flags_t flags, char *proto_version)
mobilebackup_error_t mobilebackup_receive_restore_file_received(mobilebackup_client_t client, plist.plist_t *result)
mobilebackup_error_t mobilebackup_receive_restore_application_received(mobilebackup_client_t client, plist.plist_t *result)
mobilebackup_error_t mobilebackup_send_restore_complete(mobilebackup_client_t client)
mobilebackup_error_t mobilebackup_send_error(mobilebackup_client_t client, char *reason)
cdef class MobileBackupError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
MOBILEBACKUP_E_SUCCESS: "Success",
MOBILEBACKUP_E_INVALID_ARG: "Invalid argument",
MOBILEBACKUP_E_PLIST_ERROR: "Property list error",
MOBILEBACKUP_E_MUX_ERROR: "MUX error",
MOBILEBACKUP_E_SSL_ERROR: "SSL error",
MOBILEBACKUP_E_RECEIVE_TIMEOUT: "Receive timeout",
MOBILEBACKUP_E_BAD_VERSION: "Bad version",
MOBILEBACKUP_E_REPLY_NOT_OK: "Reply not OK",
MOBILEBACKUP_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class MobileBackupClient(PropertyListService):
__service_name__ = "com.apple.mobilebackup"
cdef mobilebackup_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(mobilebackup_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef mobilebackup_error_t err
if self._c_client is not NULL:
err = mobilebackup_client_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return MobileBackupError(ret)
cdef inline int16_t _send(self, plist.plist_t node):
return mobilebackup_send(self._c_client, node)
cdef inline int16_t _receive(self, plist.plist_t* node):
return mobilebackup_receive(self._c_client, node)
cdef request_backup(self, plist.Node backup_manifest, bytes base_path, bytes proto_version):
self.handle_error(mobilebackup_request_backup(self._c_client, backup_manifest._c_node, base_path, proto_version))
cdef send_backup_file_received(self):
self.handle_error(mobilebackup_send_backup_file_received(self._c_client))
cdef request_restore(self, plist.Node backup_manifest, int flags, proto_version):
self.handle_error(mobilebackup_request_restore(self._c_client, backup_manifest._c_node, <mobilebackup_flags_t>flags, proto_version))
cpdef plist.Node receive_restore_file_received(self):
cdef:
plist.plist_t c_node = NULL
mobilebackup_error_t err
err = mobilebackup_receive_restore_file_received(self._c_client, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cpdef plist.Node receive_restore_application_received(self):
cdef:
plist.plist_t c_node = NULL
mobilebackup_error_t err
err = mobilebackup_receive_restore_application_received(self._c_client, &c_node)
try:
self.handle_error(err)
return plist.plist_t_to_node(c_node)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
raise
cdef send_restore_complete(self):
self.handle_error(mobilebackup_send_restore_complete(self._c_client))
cdef send_error(self, bytes reason):
self.handle_error(mobilebackup_send_error(self._c_client, reason))

View File

@@ -1,123 +0,0 @@
cdef extern from "libimobiledevice/mobilebackup2.h":
cdef struct mobilebackup2_client_private:
pass
ctypedef mobilebackup2_client_private *mobilebackup2_client_t
ctypedef enum mobilebackup2_error_t:
MOBILEBACKUP2_E_SUCCESS = 0
MOBILEBACKUP2_E_INVALID_ARG = -1
MOBILEBACKUP2_E_PLIST_ERROR = -2
MOBILEBACKUP2_E_MUX_ERROR = -3
MOBILEBACKUP2_E_SSL_ERROR = -4
MOBILEBACKUP2_E_RECEIVE_TIMEOUT = -5
MOBILEBACKUP2_E_BAD_VERSION = -6
MOBILEBACKUP2_E_REPLY_NOT_OK = -7
MOBILEBACKUP2_E_NO_COMMON_VERSION = -8
MOBILEBACKUP2_E_UNKNOWN_ERROR = -256
mobilebackup2_error_t mobilebackup2_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, mobilebackup2_client_t * client)
mobilebackup2_error_t mobilebackup2_client_free(mobilebackup2_client_t client)
mobilebackup2_error_t mobilebackup2_send_message(mobilebackup2_client_t client, char *message, plist.plist_t options)
mobilebackup2_error_t mobilebackup2_receive_message(mobilebackup2_client_t client, plist.plist_t *msg_plist, char **dlmessage)
mobilebackup2_error_t mobilebackup2_send_raw(mobilebackup2_client_t client, char *data, uint32_t length, uint32_t *bytes)
mobilebackup2_error_t mobilebackup2_receive_raw(mobilebackup2_client_t client, char *data, uint32_t length, uint32_t *bytes)
mobilebackup2_error_t mobilebackup2_version_exchange(mobilebackup2_client_t client, double local_versions[], char count, double *remote_version)
mobilebackup2_error_t mobilebackup2_send_request(mobilebackup2_client_t client, char *request, char *target_identifier, char *source_identifier, plist.plist_t options)
mobilebackup2_error_t mobilebackup2_send_status_response(mobilebackup2_client_t client, int status_code, char *status1, plist.plist_t status2)
cdef class MobileBackup2Error(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
MOBILEBACKUP2_E_SUCCESS: "Success",
MOBILEBACKUP2_E_INVALID_ARG: "Invalid argument",
MOBILEBACKUP2_E_PLIST_ERROR: "Property list error",
MOBILEBACKUP2_E_MUX_ERROR: "MUX error",
MOBILEBACKUP2_E_SSL_ERROR: "SSL error",
MOBILEBACKUP2_E_RECEIVE_TIMEOUT: "Receive timeout",
MOBILEBACKUP2_E_BAD_VERSION: "Bad version",
MOBILEBACKUP2_E_REPLY_NOT_OK: "Reply not OK",
MOBILEBACKUP2_E_NO_COMMON_VERSION: "No common version",
MOBILEBACKUP2_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class MobileBackup2Client(PropertyListService):
__service_name__ = "com.apple.mobilebackup2"
cdef mobilebackup2_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(mobilebackup2_client_new(device._c_dev, descriptor._c_service_descriptor, &self._c_client))
def __dealloc__(self):
cdef mobilebackup2_error_t err
if self._c_client is not NULL:
err = mobilebackup2_client_free(self._c_client)
self.handle_error(err)
cdef inline BaseError _error(self, int16_t ret):
return MobileBackup2Error(ret)
cpdef send_message(self, bytes message, plist.Node options):
self.handle_error(mobilebackup2_send_message(self._c_client, message, options._c_node))
cpdef tuple receive_message(self):
cdef:
char* dlmessage = NULL
plist.plist_t c_node = NULL
mobilebackup2_error_t err
err = mobilebackup2_receive_message(self._c_client, &c_node, &dlmessage)
try:
self.handle_error(err)
return (plist.plist_t_to_node(c_node), <bytes>dlmessage)
except BaseError, e:
if c_node != NULL:
plist.plist_free(c_node)
if dlmessage != NULL:
free(dlmessage)
raise
cpdef int send_raw(self, bytes data, int length):
cdef:
uint32_t bytes_recvd = 0
mobilebackup2_error_t err
err = mobilebackup2_send_raw(self._c_client, data, length, &bytes_recvd)
try:
self.handle_error(err)
return <bint>bytes_recvd
except BaseError, e:
raise
cpdef int receive_raw(self, bytearray data, int length):
cdef:
uint32_t bytes_recvd = 0
mobilebackup2_error_t err
err = mobilebackup2_receive_raw(self._c_client, data, length, &bytes_recvd)
# Throwing an exception when we test if theres more data to read is excessive
if err == -1 and bytes_recvd == 0:
return 0
try:
self.handle_error(err)
return <bint>bytes_recvd
except BaseError, e:
raise
cpdef float version_exchange(self, double[::1] local_versions):
cdef:
double[::1] temp = None
double remote_version = 0.0
mobilebackup2_error_t err
err = mobilebackup2_version_exchange(self._c_client, &local_versions[0], len(local_versions), &remote_version)
try:
self.handle_error(err)
return <float>remote_version
except BaseError, e:
raise
cpdef send_request(self, bytes request, bytes target_identifier, bytes source_identifier, plist.Node options):
self.handle_error(mobilebackup2_send_request(self._c_client, request, target_identifier, source_identifier, options._c_node))
cpdef send_status_response(self, int status_code, bytes status1, plist.Node status2):
self.handle_error(mobilebackup2_send_status_response(self._c_client, status_code, status1, status2._c_node))

View File

@@ -1,164 +0,0 @@
cdef extern from "libimobiledevice/mobilesync.h":
cdef struct mobilesync_client_private:
pass
ctypedef mobilesync_client_private *mobilesync_client_t
ctypedef enum mobilesync_error_t:
MOBILESYNC_E_SUCCESS = 0
MOBILESYNC_E_INVALID_ARG = -1
MOBILESYNC_E_PLIST_ERROR = -2
MOBILESYNC_E_MUX_ERROR = -3
MOBILESYNC_E_SSL_ERROR = -4
MOBILESYNC_E_RECEIVE_TIMEOUT = -5
MOBILESYNC_E_BAD_VERSION = -6
MOBILESYNC_E_SYNC_REFUSED = -7
MOBILESYNC_E_CANCELLED = -8
MOBILESYNC_E_WRONG_DIRECTION = -9
MOBILESYNC_E_NOT_READY = -10
MOBILESYNC_E_UNKNOWN_ERROR = -256
ctypedef enum mobilesync_sync_type_t:
MOBILESYNC_SYNC_TYPE_FAST
MOBILESYNC_SYNC_TYPE_SLOW
MOBILESYNC_SYNC_TYPE_RESET
ctypedef struct mobilesync_anchors:
char *device_anchor
char *host_anchor
ctypedef mobilesync_anchors *mobilesync_anchors_t
mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client)
mobilesync_error_t mobilesync_client_free(mobilesync_client_t client)
mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist.plist_t *plist)
mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist.plist_t plist)
mobilesync_error_t mobilesync_start(mobilesync_client_t client, char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description)
mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, char* reason)
mobilesync_error_t mobilesync_finish(mobilesync_client_t client)
mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client)
mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client)
mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist.plist_t *entities, uint8_t *is_last_record, plist.plist_t *actions)
mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client)
mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client)
mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist.plist_t changes, uint8_t is_last_record, plist.plist_t actions)
mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist.plist_t *mapping)
mobilesync_anchors_t mobilesync_anchors_new(char *device_anchor, char *computer_anchor)
void mobilesync_anchors_free(mobilesync_anchors_t anchors)
plist.plist_t mobilesync_actions_new()
void mobilesync_actions_add(plist.plist_t actions, ...)
void mobilesync_actions_free(plist.plist_t actions)
SYNC_TYPE_FAST = MOBILESYNC_SYNC_TYPE_FAST
SYNC_TYPE_SLOW = MOBILESYNC_SYNC_TYPE_SLOW
SYNC_TYPE_RESET = MOBILESYNC_SYNC_TYPE_RESET
cdef class MobileSyncError(BaseError):
def __init__(self, *args, **kwargs):
self._lookup_table = {
MOBILESYNC_E_SUCCESS: "Success",
MOBILESYNC_E_INVALID_ARG: "Invalid argument",
MOBILESYNC_E_PLIST_ERROR: "Property list error",
MOBILESYNC_E_MUX_ERROR: "MUX error",
MOBILESYNC_E_SSL_ERROR: "SSL error",
MOBILESYNC_E_RECEIVE_TIMEOUT: "Receive timeout",
MOBILESYNC_E_BAD_VERSION: "Bad version",
MOBILESYNC_E_SYNC_REFUSED: "Sync refused",
MOBILESYNC_E_CANCELLED: "Sync cancelled",
MOBILESYNC_E_WRONG_DIRECTION: "Wrong sync direction",
MOBILESYNC_E_NOT_READY: "Not ready to receive changes",
MOBILESYNC_E_UNKNOWN_ERROR: "Unknown error"
}
BaseError.__init__(self, *args, **kwargs)
cdef class MobileSyncClient(DeviceLinkService):
__service_name__ = "com.apple.mobilesync"
cdef mobilesync_client_t _c_client
def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
self.handle_error(mobilesync_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
def __dealloc__(self):
cdef mobilesync_error_t err
if self._c_client is not NULL:
err = mobilesync_client_free(self._c_client)
self.handle_error(err)
cpdef tuple start(self, bytes data_class, bytes device_anchor, bytes host_anchor):
cdef:
mobilesync_anchors_t anchors = NULL
mobilesync_sync_type_t sync_type
uint64_t computer_data_class_version = 1
uint64_t device_data_class_version
char* error_description = NULL
if device_anchor is None:
anchors = mobilesync_anchors_new(NULL, host_anchor)
else:
anchors = mobilesync_anchors_new(device_anchor, host_anchor)
try:
self.handle_error(mobilesync_start(self._c_client, data_class, anchors, computer_data_class_version, &sync_type, &device_data_class_version, &error_description))
return (sync_type, <bint>computer_data_class_version, <bint>device_data_class_version, <bytes>error_description)
except Exception, e:
raise
finally:
mobilesync_anchors_free(anchors)
cpdef finish(self):
self.handle_error(mobilesync_finish(self._c_client))
cpdef cancel(self, bytes reason):
self.handle_error(mobilesync_cancel(self._c_client, reason))
cpdef get_all_records_from_device(self):
self.handle_error(mobilesync_get_all_records_from_device(self._c_client))
cpdef get_changes_from_device(self):
self.handle_error(mobilesync_get_changes_from_device(self._c_client))
cpdef tuple receive_changes(self):
cdef:
plist.plist_t entities = NULL
uint8_t is_last_record = 0
plist.plist_t actions = NULL
try:
self.handle_error(mobilesync_receive_changes(self._c_client, &entities, &is_last_record, &actions))
return (plist.plist_t_to_node(entities), <bint>is_last_record, plist.plist_t_to_node(actions))
except Exception, e:
if entities != NULL:
plist.plist_free(entities)
if actions != NULL:
plist.plist_free(actions)
raise
cpdef acknowledge_changes_from_device(self):
self.handle_error(mobilesync_acknowledge_changes_from_device(self._c_client))
cpdef ready_to_send_changes_from_computer(self):
self.handle_error(mobilesync_ready_to_send_changes_from_computer(self._c_client))
cpdef send_changes(self, plist.Node changes, bint is_last_record, plist.Node actions):
self.handle_error(mobilesync_send_changes(self._c_client, changes._c_node, is_last_record, actions._c_node))
cpdef remap_identifiers(self):
cdef plist.plist_t remapping = NULL
try:
self.handle_error(mobilesync_remap_identifiers(self._c_client, &remapping))
return plist.plist_t_to_node(remapping)
except Exception, e:
if remapping != NULL:
plist.plist_free(remapping)
raise
cdef int16_t _send(self, plist.plist_t node):
return mobilesync_send(self._c_client, node)
cdef int16_t _receive(self, plist.plist_t* node):
return mobilesync_receive(self._c_client, node)
cdef inline BaseError _error(self, int16_t ret):
return MobileSyncError(ret)

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