mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-18 19:23:43 +01:00
fix submodule
This commit is contained in:
12
.gitmodules
vendored
12
.gitmodules
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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/
|
|
||||||
@@ -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!
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
# libimobiledevice-glue
|
|
||||||
|
|
||||||
Library with common code used by the libraries and tools around the
|
|
||||||
**libimobiledevice** project.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 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
|
|
||||||
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
"
|
|
||||||
@@ -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
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
* text=auto
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
AUTOMAKE_OPTIONS = foreign
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
|
||||||
SUBDIRS =
|
|
||||||
if HAVE_WIRELESS_PAIRING
|
|
||||||
SUBDIRS += ed25519 libsrp6a-sha512
|
|
||||||
endif
|
|
||||||
@@ -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).
|
|
||||||
|
|
||||||
@@ -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.
|
|
||||||
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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_ */
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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_ */
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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));
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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 */
|
|
||||||
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
|
|
||||||
@@ -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!
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -1,196 +0,0 @@
|
|||||||
# libimobiledevice
|
|
||||||
|
|
||||||
*A library to communicate with services on iOS devices using native protocols.*
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
|
||||||
@@ -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.
|
|
||||||
"
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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)
|
|
||||||
@@ -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
|
|
||||||
@@ -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)
|
|
||||||
@@ -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)
|
|
||||||
@@ -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
|
|
||||||
@@ -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)
|
|
||||||
@@ -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"
|
|
||||||
@@ -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)
|
|
||||||
@@ -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)
|
|
||||||
@@ -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)
|
|
||||||
@@ -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)
|
|
||||||
@@ -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))
|
|
||||||
@@ -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))
|
|
||||||
@@ -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
Reference in New Issue
Block a user