Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37477657
en ru br
ALT Linux repos
S:1.2.3-alt2
5.0: 1.0.4-alt0.20080218
4.1: 1.0.4-alt0.20080218

Group :: System/Base
RPM: isomd5sum

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

pax_global_header00006660000000000000000000000064122641201720014507gustar00rootroot0000000000000052 comment=ce3cfcfdb5077551d7047e3c2a96aa1fd752a7cb
isomd5sum-1.0.12/000075500000000000000000000000001226412017200135135ustar00rootroot00000000000000isomd5sum-1.0.12/.gitignore000064400000000000000000000000641226412017200155030ustar00rootroot00000000000000checkisomd5
implantisomd5
*.o
*.so
*~
*.a
*.tar.bz2
isomd5sum-1.0.12/COPYING000064400000000000000000000430761226412017200145600ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, 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 Library 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

Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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 Library General
Public License instead of this License.
isomd5sum-1.0.12/Makefile000064400000000000000000000046501226412017200151600ustar00rootroot00000000000000PYVER := $(shell python -c 'import sys; print sys.version[0:3]')
PYTHON = python$(PYVER)
PYTHONINCLUDE = /usr/include/$(PYTHON)

VERSION=1.0.12

ifneq (,$(filter sparc64 ppc64 ppc64le x86_64 s390x aarch64,$(shell uname -m)))
LIBDIR = lib64
else
LIBDIR = lib
endif

CFLAGS += -Wall -Werror -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -fPIC -I$(PYTHONINCLUDE)

OBJECTS = md5.o libimplantisomd5.o checkisomd5.o implantisomd5
SOURCES = $(patsubst %.o,%.c,$(OBJECTS))
LDFLAGS += -fPIC

PYOBJS = pyisomd5sum.o libcheckisomd5.a libimplantisomd5.a

all: implantisomd5 checkisomd5 pyisomd5sum.so libimplantisomd5.a libcheckisomd5.a

%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -O -o $@ $<

implantisomd5: implantisomd5.o libimplantisomd5.a
$(CC) $(CPPFLAGS) $(CFLAGS) implantisomd5.o libimplantisomd5.a -lpopt $(LDFLAGS) -o implantisomd5

checkisomd5: checkisomd5.o libcheckisomd5.a
$(CC) $(CPPFLAGS) $(CFLAGS) checkisomd5.o libcheckisomd5.a -lpopt $(LDFLAGS) -o checkisomd5

libimplantisomd5.a: libimplantisomd5.a(libimplantisomd5.o md5.o)

libcheckisomd5.a: libcheckisomd5.a(libcheckisomd5.o md5.o)

pyisomd5sum.so: $(PYOBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) -shared -g -fpic $(PYOBJS) $(LDFLAGS) -o pyisomd5sum.so

install: all install-bin install-python install-devel

install-bin:
install -d -m 0755 $(DESTDIR)/usr/bin
install -d -m 0755 $(DESTDIR)/usr/share/man/man1
install -m 0755 implantisomd5 $(DESTDIR)/usr/bin
install -m 0755 checkisomd5 $(DESTDIR)/usr/bin
install -m 0644 implantisomd5.1 $(DESTDIR)/usr/share/man/man1
install -m 0644 checkisomd5.1 $(DESTDIR)/usr/share/man/man1

install-python:
install -d -m 0755 $(DESTDIR)/usr/$(LIBDIR)/$(PYTHON)/site-packages
install -m 0755 pyisomd5sum.so $(DESTDIR)/usr/$(LIBDIR)/$(PYTHON)/site-packages

install-devel:
install -d -m 0755 $(DESTDIR)/usr/include
install -d -m 0755 $(DESTDIR)/usr/$(LIBDIR)
install -m 0644 libimplantisomd5.h $(DESTDIR)/usr/include/
install -m 0644 libcheckisomd5.h $(DESTDIR)/usr/include/
install -m 0644 libimplantisomd5.a $(DESTDIR)/usr/$(LIBDIR)
install -m 0644 libcheckisomd5.a $(DESTDIR)/usr/$(LIBDIR)

clean:
rm -f *.o *.so *.pyc *.a .depend *~
rm -f implantisomd5 checkisomd5

tag:
@git tag -a -m "Tag as $(VERSION)" -f $(VERSION)
@echo "Tagged as $(VERSION)"

archive:
@git archive --format=tar --prefix=isomd5sum-$(VERSION)/ HEAD |bzip2 > isomd5sum-$(VERSION).tar.bz2
@echo "The final archive is in isomd5sum-$(VERSION).tar.bz2"
isomd5sum-1.0.12/README000064400000000000000000000011021226412017200143650ustar00rootroot00000000000000isomd5sum provides a way of making use of the ISO9660 application data
area to store md5sum data about the iso. This allows you to check the
iso given nothing more than the iso itself.

isomd5sum is hosted as a fedorahosted project. The source can be
grabbed via git with
git clone git://git.fedorahosted.org/isomd5sum.git
or browsed via gitweb at
http://git.fedorahosted.org/git/?p=isomd5sum.git;a=summary

Releases of isomd5sum are located at
http://fedorahosted.org/releases/i/s/isomd5sum

You can send questions, enhancements, etc to anaconda-devel-list@redhat.com.
isomd5sum-1.0.12/checkisomd5.1000064400000000000000000000024211226412017200157720ustar00rootroot00000000000000.TH "CHECKISOMD5" "1"
.SH "NAME"
checkisomd5 \(em check an MD5 checksum implanted by \fBimplantisomd5\fR
.SH "SYNOPSIS"
.PP
\fBcheckisomd5\fR [\fB\-\-md5sumonly\fP] [\fB\-\-verbose\fP] [\fB\-\-gauge\fP] [isofilename | blockdevice ]
.SH "DESCRIPTION"
.PP
This manual page documents briefly the \fBcheckisomd5\fR command. \fBcheckisomd5\fR is a program that checks an embedded MD5 checksum in a ISO9660 image (.iso), or block device. The checksum is embedded by the corresponding \fBimplantisomd5\fR command.
.PP
The check can be aborted by pressing Esc key.
.SH "EXIT STATUS"
.PP
Program returns exit status 0 if the checksum is correct, 1 if the checksum is incorrect or non-existent, or 2 if the check was aborted.
.SH "OPTIONS"
.IP "\fB\-\-md5sumonly\fP" 10
Do not check the target. Instead, output human-readable information about the target's checksums.
.IP "\fB\-\-verbose\fP" 10
Display human-readable progress as the target is checked. Without this option, nothing is outputted except errors.
.IP "\fB\-\-gauge\fP" 10
Display a series of numbers from 0 to 100, corresponding to check progress. This output can be piped to \fBdialog \-\-gauge\fR for a user-friendly progress bar.
.SH "SEE ALSO"
.PP
implantisomd5 (1).
.\" created by instant / docbook-to-man, Thu 07 Feb 2008, 13:43
isomd5sum-1.0.12/checkisomd5.c000064400000000000000000000113511226412017200160560ustar00rootroot00000000000000/*
* checkosmd5 - simple program to check implanted md5sum
* Copyright (C) 2001-2013 Red Hat, Inc.
* Michael Fulbright <msf@redhat.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <popt.h>
#include <termios.h>

#include "md5.h"
#include "libcheckisomd5.h"

struct progressCBData {
int verbose;
int gauge;
int gaugeat;
};

int user_bailing_out() {
int retval = 0;
struct timeval timev;
fd_set rfds;
char ch;

FD_ZERO(&rfds);
FD_SET(0,&rfds);

timev.tv_sec = 0;
timev.tv_usec = 0;

if (select(1, &rfds, NULL, NULL, &timev))
if ((ch = getchar()) == 27)
retval = 1;

return retval;
}

static int outputCB(void *co, long long offset, long long total) {
struct progressCBData *data = co;
int gaugeval = -1;

if (data->verbose) {
printf("\rChecking: %05.1f%%", (100.0*offset)/(total));
fflush(stdout);
}
if (data->gauge) {
gaugeval = (100.0*offset)/(total);
if (gaugeval != data->gaugeat) {
printf("%d\n", gaugeval);
fflush(stdout);
data->gaugeat = gaugeval;
}
}

return user_bailing_out();
}

static void usage(void) {
fprintf(stderr, "Usage: checkisomd5 [--md5sumonly] [--verbose] [--gauge] <isofilename>|<blockdevice>\n\n");
exit(1);
}


/* Process the result code and return the proper exit status value
*
* return 1 for failures, 0 for good checksum and 2 if aborted.
*/
int processExitStatus(int rc) {
char * result;
int exit_rc;

switch (rc) {
case ISOMD5SUM_CHECK_FAILED:
result = "FAIL.\n\nIt is not recommended to use this media.";
exit_rc = 1;
break;
case ISOMD5SUM_CHECK_ABORTED:
result = "UNKNOWN.\n\nThe media check was aborted.";
exit_rc = 2;
break;
case ISOMD5SUM_CHECK_NOT_FOUND:
result = "NA.\n\nNo checksum information available, unable to verify media.";
exit_rc = 1;
break;
case ISOMD5SUM_FILE_NOT_FOUND:
result = "NA.\n\nFile not found.";
exit_rc = 1;
break;
case ISOMD5SUM_CHECK_PASSED:
result = "PASS.\n\nIt is OK to use this media.";
exit_rc = 0;
break;
default:
result = "checkisomd5 ERROR - bad return value";
exit_rc = 1;
break;
}

fprintf(stderr, "\nThe media check is complete, the result is: %s\n", result);

return(exit_rc);
}


int main(int argc, char **argv) {
int rc;
const char **args;
int md5only;
int help;
struct progressCBData data;
poptContext optCon;

memset(&data, 0, sizeof(struct progressCBData));

md5only = 0;
help = 0;
data.verbose = 0;
data.gauge = 0;

struct poptOption options[] = {
{ "md5sumonly", 'o', POPT_ARG_NONE, &md5only, 0 },
{ "verbose", 'v', POPT_ARG_NONE, &data.verbose, 0 },
{ "gauge", 'g', POPT_ARG_NONE, &data.gauge, 0},
{ "help", 'h', POPT_ARG_NONE, &help, 0},
{ 0, 0, 0, 0, 0}
};

static struct termios oldt, newt;

optCon = poptGetContext("checkisomd5", argc, (const char **)argv, options, 0);

if ((rc = poptGetNextOpt(optCon)) < -1) {
fprintf(stderr, "bad option %s: %s\n",
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
poptStrerror(rc));
exit(1);
}

if (help)
usage();

args = poptGetArgs(optCon);
if (!args || !args[0] || !args[0][0])
usage();

if (md5only|data.verbose) {
rc = printMD5SUM((char *)args[0]);
if (rc < 0) {
exit(processExitStatus(rc));
}
}

if (md5only)
exit(0);

printf("Press [Esc] to abort check.\n");

tcgetattr(0, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
tcsetattr(0, TCSANOW, &newt);
rc = mediaCheckFile((char *)args[0], outputCB, &data);
tcsetattr(0, TCSANOW, &oldt);

if (data.verbose)
printf("\n");

exit(processExitStatus(rc));
}

isomd5sum-1.0.12/implantisomd5.1000064400000000000000000000016051226412017200163640ustar00rootroot00000000000000.TH "IMPLANTISOMD5" "1"
.SH "NAME"
implantisomd5 \(em implant an MD5 checksum in an ISO9660 image
.SH "SYNOPSIS"
.PP
\fBimplantisomd5\fR [\fB\-\-force\fP] [\fB\-\-supported-iso\fP] [isofilename]
.SH "DESCRIPTION"
.PP
This manual page documents briefly the \fBimplantisomd5\fR command. \fBimplantisomd5\fR is a program that embeds an MD5 checksum in an unused section of and ISO9660 (.iso) image. This checksum can later be compared to the .iso, or a block device, using the corresponding \fBcheckisomd5\fR command.
.SH "OPTIONS"
.IP "\fB\-\-force\fP" 10
Force an existing checksum to be overwritten.
.IP "\fB\-\-supported-iso\fP" 10
Indicate that the image will be written to a "supported" media, such as pressed CD. On Red Hat-based Anaconda installers, this bypasses the prompt to check the CD.
.SH "SEE ALSO"
.PP
checkisomd5 (1).
.\" created by instant / docbook-to-man, Thu 07 Feb 2008, 12:11
isomd5sum-1.0.12/implantisomd5.c000064400000000000000000000042251226412017200164470ustar00rootroot00000000000000/*
* simple program to insert an md5sum into application data area of iso99660
* Copyright (C) 2001-2013 Red Hat, Inc.
* Michael Fulbright <msf@redhat.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <popt.h>

#include "md5.h"
#include "libimplantisomd5.h"


static void usage(void) {
fprintf(stderr, "implantisomd5: implantisomd5 [--force] [--supported-iso] <isofilename>\n");
exit(1);
}


int main(int argc, char **argv) {
int rc;
char *errstr;
const char **args;

int forceit=0;
int supported=0;
int help=0;

poptContext optCon;
struct poptOption options[] = {
{ "force", 'f', POPT_ARG_NONE, &forceit, 0 },
{ "supported-iso", 'S', POPT_ARG_NONE, &supported, 0 },
{ "help", 'h', POPT_ARG_NONE, &help, 0},
{ 0, 0, 0, 0, 0}
};


optCon = poptGetContext("implantisomd5", argc, (const char **)argv, options, 0);

if ((rc = poptGetNextOpt(optCon)) < -1) {
fprintf(stderr, "bad option %s: %s\n",
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
poptStrerror(rc));
exit(1);
}

if (help)
usage();

args = poptGetArgs(optCon);
if (!args || !args[0] || !args[0][0])
usage();

rc = implantISOFile((char *)args[0], supported, forceit, 0, &errstr);
if (rc) {
fprintf(stderr, "ERROR: ");
fprintf(stderr, errstr, (char *)args[0]);
exit(1);
} else {
exit(0);
}
}
isomd5sum-1.0.12/libcheckisomd5.c000064400000000000000000000270411226412017200165500ustar00rootroot00000000000000/*
* Copyright (C) 2001-2013 Red Hat, Inc.
*
* Michael Fulbright <msf@redhat.com>
* Dustin Kirkland <dustin.dirkland@gmail.com>
* Added support for checkpoint fragment sums;
* Exits media check as soon as bad fragment md5sum'ed
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#include "md5.h"
#include "libcheckisomd5.h"

#define APPDATA_OFFSET 883
#define SIZE_OFFSET 84

/* Length in characters of string used for fragment md5sum checking */
#define FRAGMENT_SUM_LENGTH 60

#define MAX(x, y) ((x > y) ? x : y)
#define MIN(x, y) ((x < y) ? x : y)

/* finds primary volume descriptor and returns info from it */
/* mediasum must be a preallocated buffer at least 33 bytes long */
/* fragmentsums must be a preallocated buffer at least FRAGMENT_SUM_LENGTH+1 bytes long */
static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *supported, char *fragmentsums, long long *fragmentcount) {
unsigned char buf[2048];
char buf2[512];
char tmpbuf[512];
int skipfnd, md5fnd, supportedfnd, fragsumfnd, fragcntfnd;
unsigned int loc;
long long offset;
char *p;

if (lseek(isofd, (off_t)(16L * 2048L), SEEK_SET) == -1)
return ((long long)-1);

offset = (16L * 2048L);
for (;1;) {
if (read(isofd, buf, 2048) <= 0)
return ((long long)-1);

if (buf[0] == 1)
/* found primary volume descriptor */
break;
else if (buf[0] == 255)
/* hit end and didn't find primary volume descriptor */
return ((long long)-1);
offset += 2048L;
}

/* read out md5sum */
memcpy(buf2, buf + APPDATA_OFFSET, 512);
buf2[511] = '\0';

*supported = 0;

md5fnd = 0;
skipfnd = 0;
fragsumfnd = 0;
fragcntfnd = 0;
supportedfnd = 0;
loc = 0;
while (loc < 512) {
if (!strncmp(buf2 + loc, "ISO MD5SUM = ", 13)) {

/* make sure we dont walk off end */
if ((loc + 32 + 13) > 511)
return -1;

memcpy(mediasum, buf2 + loc + 13, 32);
mediasum[32] = '\0';
md5fnd = 1;
loc += 45;
for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else if (!strncmp(buf2 + loc, "SKIPSECTORS = ", 14)) {
char *errptr;

/* make sure we dont walk off end */
if ((loc + 14) > 511)
return -1;

loc = loc + 14;
for (p=tmpbuf; buf2[loc] != ';' && loc < 512; p++, loc++)
*p = buf2[loc];

*p = '\0';

*skipsectors = strtol(tmpbuf, &errptr, 10);
if (errptr && *errptr) {
return -1;
} else {
skipfnd = 1;
}

for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else if (!strncmp(buf2 + loc, "RHLISOSTATUS=1", 14)) {
*supported = 1;
supportedfnd = 1;
for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else if (!strncmp(buf2 + loc, "RHLISOSTATUS=0", 14)) {
*supported = 0;
supportedfnd = 1;
for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else if (!strncmp(buf2 + loc, "FRAGMENT SUMS = ", 16)) {
/* make sure we dont walk off end */
if ((loc + FRAGMENT_SUM_LENGTH) > 511)
return -1;

memcpy(fragmentsums, buf2 + loc + 16, FRAGMENT_SUM_LENGTH);
fragmentsums[FRAGMENT_SUM_LENGTH] = '\0';
fragsumfnd = 1;
loc += FRAGMENT_SUM_LENGTH + 16;
for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else if (!strncmp(buf2 + loc, "FRAGMENT COUNT = ", 17)) {
char *errptr;
/* make sure we dont walk off end */
if ((loc + 17) > 511)
return -1;

loc = loc + 17;
for (p=tmpbuf; buf2[loc] != ';' && loc < 512; p++, loc++)
*p = buf2[loc];

*p = '\0';

*fragmentcount = strtol(tmpbuf, &errptr, 10);
if (errptr && *errptr) {
return -1;
} else {
fragcntfnd = 1;
}

for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++);
} else {
loc++;
}

if ((skipfnd & md5fnd & fragsumfnd & fragcntfnd) & supportedfnd)
break;
}

if (!(skipfnd & md5fnd))
return -1;

/* get isosize */
*isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 +
buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL;

return offset;
}

/* mediasum is the sum encoded in media, computedsum is one we compute */
/* both strings must be pre-allocated at least 33 chars in length */
static int checkmd5sum(int isofd, char *mediasum, char *computedsum, checkCallback cb, void *cbdata) {
int nread;
int i, j;
int appdata_start_offset, appdata_end_offset;
int nattempt;
int skipsectors;
int supported;
int current_fragment = 0;
int previous_fragment = 0;
unsigned int bufsize = 32768;
unsigned char md5sum[16];
unsigned char fragmd5sum[16];
unsigned int len;
unsigned char *buf;
long long isosize, offset, pvd_offset, apoff;
char fragmentsums[FRAGMENT_SUM_LENGTH+1];
char thisfragsum[FRAGMENT_SUM_LENGTH+1];
long long fragmentcount = 0;
MD5_CTX md5ctx, fragmd5ctx;

if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported, fragmentsums, &fragmentcount)) < 0)
return ISOMD5SUM_CHECK_NOT_FOUND;

/* printf("Mediasum = %s\n",mediasum); */

/* rewind, compute md5sum */
lseek(isofd, 0L, SEEK_SET);

MD5_Init(&md5ctx);

offset = 0;
apoff = pvd_offset + APPDATA_OFFSET;

buf = malloc(bufsize * sizeof(unsigned char));
if (cb)
cb(cbdata, 0, isosize - skipsectors*2048);

while (offset < isosize - skipsectors*2048) {
nattempt = MIN(isosize - skipsectors*2048 - offset, bufsize);

/* printf("%lld %lld %lld %d\n", offset, isosize, isosize-SKIPSECTORS*2048, nattempt); */

nread = read(isofd, buf, nattempt);
if (nread <= 0)
break;

if (nread > nattempt) {
nread = nattempt;
lseek(isofd, offset+nread, SEEK_SET);
}
/* overwrite md5sum we implanted with original data */
if (offset < apoff && offset+nread >= apoff) {
appdata_start_offset = apoff - offset;
appdata_end_offset = MIN(appdata_start_offset+MIN(nread, 512),
offset + nread - apoff);
len = appdata_end_offset - appdata_start_offset;
memset(buf+appdata_start_offset, ' ', len);
} else if (offset >= apoff && offset+nread < apoff + 512) {
appdata_start_offset = 0;
appdata_end_offset = nread;
len = appdata_end_offset - appdata_start_offset;
memset(buf+appdata_start_offset, ' ', len);
} else if (offset < apoff + 512 && offset+nread >= apoff + 512) {
appdata_start_offset = 0;
appdata_end_offset = apoff + 512 - offset;
len = appdata_end_offset - appdata_start_offset;
memset(buf+appdata_start_offset, ' ', len);
}

MD5_Update(&md5ctx, buf, nread);
if (fragmentcount) {
current_fragment = offset * (fragmentcount+1) / (isosize - skipsectors*2048);
/* if we're onto the next fragment, calculate the previous sum and check */
if ( current_fragment != previous_fragment ) {
memcpy(&fragmd5ctx, &md5ctx, sizeof(MD5_CTX));
MD5_Final(fragmd5sum, &fragmd5ctx);
*computedsum = '\0';
j = (current_fragment-1)*FRAGMENT_SUM_LENGTH/fragmentcount;
for (i=0; i<FRAGMENT_SUM_LENGTH/fragmentcount; i++) {
char tmpstr[2];
snprintf(tmpstr, 2, "%01x", fragmd5sum[i]);
strncat(computedsum, tmpstr, 2);
thisfragsum[i] = fragmentsums[j++];
}
thisfragsum[j] = '\0';
previous_fragment = current_fragment;
/* Exit immediately if current fragment sum is incorrect */
if (strcmp(thisfragsum, computedsum) != 0) {
return ISOMD5SUM_CHECK_FAILED;
}
}
}
offset = offset + nread;
if (cb)
if(cb(cbdata, offset, isosize - skipsectors*2048)) return ISOMD5SUM_CHECK_ABORTED;
}

if (cb)
cb(cbdata, isosize, isosize - skipsectors*2048);

sleep(1);

free(buf);

MD5_Final(md5sum, &md5ctx);

*computedsum = '\0';
for (i=0; i<16; i++) {
char tmpstr[4];
snprintf (tmpstr, 4, "%02x", md5sum[i]);
strncat(computedsum, tmpstr, 2);
}

/* printf("mediasum, computedsum = %s %s\n", mediasum, computedsum); */

if (strcmp(mediasum, computedsum))
return ISOMD5SUM_CHECK_FAILED;
else
return ISOMD5SUM_CHECK_PASSED;
}


static int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosize, int *supported, checkCallback cb, void *cbdata) {
int rc;
int skipsectors;
long long fragmentcount = 0;
char fragmentsums[FRAGMENT_SUM_LENGTH+1];

if (parsepvd(isofd, mediasum, &skipsectors, isosize, supported, fragmentsums, &fragmentcount) < 0) {
return ISOMD5SUM_CHECK_NOT_FOUND;
}

rc = checkmd5sum(isofd, mediasum, computedsum, cb, cbdata);

return rc;
}

int mediaCheckFile(char *file, checkCallback cb, void *cbdata) {
int isofd;
int rc;
char mediasum[33], computedsum[33];
long long isosize;
int supported;

isofd = open(file, O_RDONLY);

if (isofd < 0) {
return ISOMD5SUM_FILE_NOT_FOUND;
}

rc = doMediaCheck(isofd, mediasum, computedsum, &isosize, &supported, cb, cbdata);

close(isofd);

/* printf("isosize = %lld\n", isosize);
* printf("%s\n%s\n", mediasum, computedsum);
*/

return rc;
}

int printMD5SUM(char *file) {
int isofd;
char mediasum[64];
long long isosize;
char fragmentsums[FRAGMENT_SUM_LENGTH+1];
long long fragmentcount = 0;
int supported;
int skipsectors;

isofd = open(file, O_RDONLY);

if (isofd < 0) {
return ISOMD5SUM_FILE_NOT_FOUND;
}

if (parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported, fragmentsums, &fragmentcount) < 0) {
return ISOMD5SUM_CHECK_NOT_FOUND;
}

close(isofd);

printf("%s: %s\n", file, mediasum);
if ( (strlen(fragmentsums) > 0) && (fragmentcount > 0) ) {
printf("Fragment sums: %s\n", fragmentsums);
printf("Fragment count: %lld\n", fragmentcount);
printf("Supported ISO: %s\n", supported ? "yes" : "no");
}

return 0;
}
isomd5sum-1.0.12/libcheckisomd5.h000064400000000000000000000007611226412017200165550ustar00rootroot00000000000000#ifndef __LIBCHECKISOMD5_H__
#define __LIBCHECKISOMD5_H__

#define ISOMD5SUM_CHECK_PASSED 1
#define ISOMD5SUM_CHECK_FAILED 0
#define ISOMD5SUM_CHECK_ABORTED 2
#define ISOMD5SUM_CHECK_NOT_FOUND -1
#define ISOMD5SUM_FILE_NOT_FOUND -2

/* for non-zero return value, check is aborted */
typedef int (*checkCallback)(void *, long long offset, long long total);

int mediaCheckFile(char *iso, checkCallback cb, void *cbdata);
int printMD5SUM(char *file);

#endif
isomd5sum-1.0.12/libimplantisomd5.c000064400000000000000000000200021226412017200171250ustar00rootroot00000000000000/*
* Copyright (C) 2001-2013 Red Hat, Inc.
*
* Michael Fulbright <msf@redhat.com>
* Dustin Kirkland <dustin.dirkland@gmail.com>
* Added support for checkpoint fragment sums;
* Exits media check as soon as bad fragment md5sum'ed
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include "md5.h"
#include "libimplantisomd5.h"

#define APPDATA_OFFSET 883
#define SIZE_OFFSET 84

/* Length in characters of string used for fragment md5sum checking */
#define FRAGMENT_SUM_LENGTH 60
/* FRAGMENT_COUNT must be an integral divisor or FRAGMENT_SUM_LENGTH */
/* 60 => 2, 3, 4, 5, 6, 10, 12, 15, 20, or 30 */
#define FRAGMENT_COUNT 20

/* number of sectors to ignore at end of iso when computing sum */
#define SKIPSECTORS 15

#define MAX(x, y) ((x > y) ? x : y)
#define MIN(x, y) ((x < y) ? x : y)

/* finds primary volume descriptor and returns info from it */
/* mediasum must be a preallocated buffer at least 33 bytes long */
static int parsepvd(int isofd, char *mediasum, long long *isosize) {
unsigned char buf[2048];
long long offset;
unsigned char *p __attribute__((unused));

if (lseek(isofd, 16*2048, SEEK_SET) == -1)
return ((long long)-1);

offset = (16 * 2048);
for (;1;) {
if (read(isofd, buf, 2048L) == -1)
return ((long long)-1);

if (buf[0] == 1)
/* found primary volume descriptor */
break;
else if (buf[0] == 255)
/* hit end and didn't find primary volume descriptor */
return ((long long)-1);
offset += 2048L;
}

/* read out md5sum */
#if 0
memcpy(mediasum, buf + APPDATA_OFFSET + 13, 32);
mediasum[32] = '\0';

for (p=mediasum; *p; p++)
if (*p != ' ')
break;

/* if the md5sum was all spaces, we didn't find md5sum */
if (!*p)
return -1;
#endif

/* get isosize */
*isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 +
buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL;

return offset;
}


static unsigned int writeAppData(unsigned char *appdata, char *valstr, unsigned int loc) {
if (loc + strlen(valstr) > 511) {
printf("Attempted to write too much appdata, exiting...\n");
exit(-1);
}

memcpy(appdata + loc, valstr, strlen(valstr));

return loc+strlen(valstr);
}




int implantISOFile(char *fname, int supported, int forceit, int quiet, char **errstr) {
int i;
int isofd;
int nread;
int dirty;
int pvd_offset;
int current_fragment = 0;
int previous_fragment = 0;
int nattempt;
long long isosize, total;
unsigned char md5sum[16];
unsigned char fragmd5sum[16];
unsigned int loc;
unsigned int bufsize = 32768;
unsigned char *buf;
unsigned char orig_appdata[512];
unsigned char new_appdata[512];
char mediasum[33];
char md5str[40];
char fragstr[FRAGMENT_SUM_LENGTH+1];
MD5_CTX md5ctx, fragmd5ctx;

isofd = open(fname, O_RDWR);

if (isofd < 0) {
*errstr = "Error - Unable to open file %s\n\n";
return -1;
}

pvd_offset = parsepvd(isofd, mediasum, &isosize);
if (pvd_offset < 0) {
*errstr = "Could not find primary volumne!\n\n";
return -1;
}

lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET);
nread = read(isofd, orig_appdata, 512);

if (!forceit) {
dirty = 0;
for (i=0; i < 512; i++)
if (orig_appdata[i] != ' ')
dirty = 1;

if (dirty) {
*errstr = "Application data has been used - not implanting md5sum!\n";
return -1;
}
} else {
/* write out blanks to erase old app data */
lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET);
memset(new_appdata, ' ', 512);
i = write(isofd, new_appdata, 512);
if (i<0) {
printf("write failed %d\n", i);
perror("");
}
}

/* now do md5sum */
lseek(isofd, 0L, SEEK_SET);

MD5_Init(&md5ctx);
*fragstr = '\0';
buf = malloc(bufsize * sizeof(unsigned char));

total = 0;
/* read up to 15 sectors from end, due to problems reading last few */
/* sectors on burned CDs */
while (total < isosize - SKIPSECTORS*2048) {
nattempt = MIN(isosize - SKIPSECTORS*2048 - total, bufsize);
nread = read(isofd, buf, nattempt);

if (nread <= 0)
break;

MD5_Update(&md5ctx, buf, nread);

/* if we're onto the next fragment, calculate the previous sum and write */
current_fragment = total * (FRAGMENT_COUNT+1) / (isosize - SKIPSECTORS*2048);
if ( current_fragment != previous_fragment ) {
memcpy(&fragmd5ctx, &md5ctx, sizeof(MD5_CTX));
MD5_Final(fragmd5sum, &fragmd5ctx);
for (i=0; i<FRAGMENT_SUM_LENGTH/FRAGMENT_COUNT; i++) {
char tmpstr[2];
snprintf(tmpstr, 2, "%01x", fragmd5sum[i]);
strncat(fragstr, tmpstr, 2);
}
/* printf("\nFragment [%i]: %s\n", previous_fragment, fragstr); */
previous_fragment = current_fragment;
}

total = total + nread;
}
free(buf);

MD5_Final(md5sum, &md5ctx);

*md5str = '\0';
for (i=0; i<16; i++) {
char tmpstr[4];
snprintf (tmpstr, 4, "%02x", md5sum[i]);
strncat(md5str, tmpstr, 2);
}

if (!quiet) {
printf("Inserting md5sum into iso image...\n");
printf("md5 = %s\n", md5str);
printf("Inserting fragment md5sums into iso image...\n");
printf("fragmd5 = %s\n", fragstr);
printf("frags = %d\n", FRAGMENT_COUNT);
}
/* memcpy(new_appdata, orig_appdata, 512); */
memset(new_appdata, ' ', 512);

loc = 0;
loc = writeAppData(new_appdata, "ISO MD5SUM = ", loc);
loc = writeAppData(new_appdata, md5str, loc);
loc = writeAppData(new_appdata, ";", loc);

buf = malloc(512 * sizeof(unsigned char));
snprintf((char *)buf, 512, "SKIPSECTORS = %d", SKIPSECTORS);

loc = writeAppData(new_appdata, (char *)buf, loc);
loc = writeAppData(new_appdata, ";", loc);
free(buf);

if (supported) {
if (!quiet)
printf("Setting supported flag to 1\n");
loc = writeAppData(new_appdata, "RHLISOSTATUS=1", loc);
} else {
if (!quiet)
printf("Setting supported flag to 0\n");
loc = writeAppData(new_appdata, "RHLISOSTATUS=0", loc);
}

loc = writeAppData(new_appdata, ";", loc);

loc = writeAppData(new_appdata, "FRAGMENT SUMS = ", loc);
loc = writeAppData(new_appdata, fragstr, loc);
loc = writeAppData(new_appdata, ";", loc);

buf = malloc(512 * sizeof(unsigned char));
snprintf((char *)buf, 512, "FRAGMENT COUNT = %d", FRAGMENT_COUNT);
loc = writeAppData(new_appdata, (char *)buf, loc);
loc = writeAppData(new_appdata, ";", loc);
free(buf);

loc = writeAppData(new_appdata, "THIS IS NOT THE SAME AS RUNNING MD5SUM ON THIS ISO!!", loc);

i = lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET);
if (i<0)
printf("seek failed\n");

i = write(isofd, new_appdata, 512);
if (i<0) {
printf("write failed %d\n", i);
perror("");
}

close(isofd);
errstr = NULL;
return 0;
}
isomd5sum-1.0.12/libimplantisomd5.h000064400000000000000000000002331226412017200171360ustar00rootroot00000000000000#ifndef __LIBIMPLANTISOMD5_H__
#define __LIBIMPLANTISOMD5_H__
int implantISOFile(char *iso, int supported, int forceit, int quiet, char **errstr);
#endif

isomd5sum-1.0.12/md5.c000064400000000000000000000224011226412017200143430ustar00rootroot00000000000000/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Modified 12 June 2003 Jeremy Katz <katzj@redhat.com> to handle
* endianness better
*
*/

#include <string.h>
#include <endian.h>
#include "md5.h"

void MD5_Transform(uint32 *buf, uint32 const *in);

#define IS_BIG_ENDIAN() (__BYTE_ORDER == __BIG_ENDIAN)
#define IS_LITTLE_ENDIAN() (__BYTE_ORDER == __LITTLE_ENDIAN)

static void byteReverse(unsigned char *buf, unsigned longs);

#ifndef ASM_MD5
/*
* Note: this code is harmless on little-endian machines.
*/
static void byteReverse(unsigned char *buf, unsigned longs)
{
uint32 t;
do {
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32 *) buf = t;
buf += 4;
} while (--longs);
}
#endif

/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void MD5_Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301U;
ctx->buf[1] = 0xefcdab89U;
ctx->buf[2] = 0x98badcfeU;
ctx->buf[3] = 0x10325476U;

ctx->bits[0] = 0;
ctx->bits[1] = 0;


if (IS_BIG_ENDIAN())
ctx->doByteReverse = 1;
else
ctx->doByteReverse = 0;
}

/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void MD5_Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
{
uint32 t;

/* Update bitcount */

t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;

t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */

/* Handle any leading odd-sized chunks */

if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;

t = 64 - t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
if (ctx->doByteReverse) byteReverse(ctx->in, 16);
MD5_Transform(ctx->buf, (uint32 *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */

while (len >= 64) {
memcpy(ctx->in, buf, 64);
if (ctx->doByteReverse) byteReverse(ctx->in, 16);
MD5_Transform(ctx->buf, (uint32 *) ctx->in);
buf += 64;
len -= 64;
}

/* Handle any remaining bytes of data. */

memcpy(ctx->in, buf, len);
}

/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void MD5_Final(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;

/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;

/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;

/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;

/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
if (ctx->doByteReverse) byteReverse(ctx->in, 16);
MD5_Transform(ctx->buf, (uint32 *) ctx->in);

/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
if (ctx->doByteReverse) byteReverse(ctx->in, 14);

/* Append length in bits and transform */
memcpy(ctx->in+56, ctx->bits, sizeof(ctx->bits));

MD5_Transform(ctx->buf, (uint32 *) ctx->in);
if (ctx->doByteReverse) byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}

#ifndef ASM_MD5

/* The four core functions - F1 is optimized somewhat */

/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )

/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void MD5_Transform(uint32 buf[4], uint32 const in[16])
{
register uint32 a, b, c, d;

a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];

MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);

MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);

MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);

MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);

buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}

#endif
isomd5sum-1.0.12/md5.h000064400000000000000000000007431226412017200143550ustar00rootroot00000000000000
#ifndef MD5_H
#define MD5_H

#include <sys/types.h>

typedef u_int32_t uint32;

struct MD5Context {
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
int doByteReverse;
};

void MD5_Init(struct MD5Context *);
void MD5_Update(struct MD5Context *, unsigned const char *, unsigned);
void MD5_Final(unsigned char digest[16], struct MD5Context *);

/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
*/

typedef struct MD5Context MD5_CTX;

#endif /* MD5_H */
isomd5sum-1.0.12/pyisomd5sum.c000064400000000000000000000052151226412017200161600ustar00rootroot00000000000000/*
* Copyright (C) 2001-2013 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <Python.h>
#include <stdio.h>

#include "libcheckisomd5.h"
#include "libimplantisomd5.h"

static PyObject * doCheckIsoMD5Sum(PyObject * s, PyObject * args);
static PyObject * doImplantIsoMD5Sum(PyObject * s, PyObject * args);

static PyMethodDef isomd5sumMethods[] = {
{ "checkisomd5sum", (PyCFunction) doCheckIsoMD5Sum, METH_VARARGS, NULL },
{ "implantisomd5sum", (PyCFunction) doImplantIsoMD5Sum, METH_VARARGS, NULL },
{ NULL }
} ;

/* Call python object with offset and total
* If the object returns true return 1 to abort the check
*/
int pythonCB(void *cbdata, long long offset, long long total) {
PyObject *arglist, *result;
int rc;

arglist = Py_BuildValue("(LL)", offset, total);
result = PyObject_CallObject(cbdata, arglist);
Py_DECREF(arglist);

if (result == NULL)
return 1;

rc = PyObject_IsTrue(result);
Py_DECREF(result);
return (rc > 0);
}

static PyObject * doCheckIsoMD5Sum(PyObject * s, PyObject * args) {
PyObject *callback = NULL;
char *isofile;
int rc;

if (!PyArg_ParseTuple(args, "s|O", &isofile, &callback))
return NULL;

if (callback) {
if (!PyCallable_Check(callback)) {
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}

rc = mediaCheckFile(isofile, pythonCB, callback);
Py_DECREF(callback);
} else {
rc = mediaCheckFile(isofile, NULL, NULL);
}

return Py_BuildValue("i", rc);
}

static PyObject * doImplantIsoMD5Sum(PyObject * s, PyObject * args) {
char *isofile, *errstr;
int forceit, supported;
int rc;

if (!PyArg_ParseTuple(args, "sii", &isofile, &supported, &forceit))
return NULL;

rc = implantISOFile(isofile, supported, forceit, 1, &errstr);

return Py_BuildValue("i", rc);
}


void initpyisomd5sum(void) {
(void)Py_InitModule("pyisomd5sum", isomd5sumMethods);
}
isomd5sum-1.0.12/testpyisomd5sum.py000075500000000000000000000017311226412017200172700ustar00rootroot00000000000000#!/usr/bin/python

import os
import pyisomd5sum

# create iso file
os.system("genisoimage -quiet . > testiso.iso")

# implant it
print "Implanting -> ", pyisomd5sum.implantisomd5sum("testiso.iso", 1, 0)

# do it again without forcing, should get error
print "Implanting again w/o forcing -> ", pyisomd5sum.implantisomd5sum("testiso.iso", 1, 0)

# do it again with forcing, should work
print "Implanting again forcing -> ", pyisomd5sum.implantisomd5sum("testiso.iso", 1, 1)

# check it
print "Checking -> ",pyisomd5sum.checkisomd5sum("testiso.iso")

def callback(offset, total):
print "%s - %s" % (offset, total)

print "Run with callback"
pyisomd5sum.checkisomd5sum("testiso.iso", callback)

def callback_abort(offset, total):
print "%s - %s" % (offset, total)
if offset > 500000:
return True
return False

print "Run with callback and abort after offset of 500000"
pyisomd5sum.checkisomd5sum("testiso.iso", callback_abort)

# clean up
os.unlink("testiso.iso")
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin