diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-pwgen.c |
Initial commit
Diffstat (limited to 'support/dktools/dk-pwgen.c')
-rw-r--r-- | support/dktools/dk-pwgen.c | 2179 |
1 files changed, 2179 insertions, 0 deletions
diff --git a/support/dktools/dk-pwgen.c b/support/dktools/dk-pwgen.c new file mode 100644 index 0000000000..b5ef2d4f14 --- /dev/null +++ b/support/dktools/dk-pwgen.c @@ -0,0 +1,2179 @@ +/* + WARNING: This file was generated by dkct. + Changes you make here will be lost if dkct is run again! + You should modify the original source and run dkct on it. + Original source: dk-pwgen.ctr +*/ + +/* +Copyright (C) 2015-2017, Dirk Krause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above opyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** @file dk-pwgen.c The dk-pwgen module. +*/ + + +#line 10 "dk-pwgen.ctr" + + +#include "dk4conf.h" + +#if DK4_ON_WINDOWS +/** Allow use of the getenv() function. */ +#define _CRT_SECURE_NO_WARNINGS 1 +#endif + +#if DK4_ON_WINDOWS +#ifndef WINDOWS_H_INCLUDED +#include <windows.h> +#define WINDOWS_H_INCLUDED 1 +#endif +#ifndef WINCRYPT_H_INCLUDED +#include <wincrypt.h> +#define WINCRYPT_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_UNISTD_H +#ifndef UNISTD_H_INCLUDED +#include <unistd.h> +#define UNISTD_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SYS_TYPES_H +#ifndef SYS_TYPES_H_INCLUDED +#include <sys/types.h> +#define SYS_TYPES_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SIGNAL_H +#ifndef SIGNAL_H_INCLUDED +#include <signal.h> +#define SIGNAL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_PROCESS_H +#ifndef PROCESS_H_INCLUDED +#include <process.h> +#define PROCESS_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_IO_H +#ifndef IO_H_INCLUDED +#include <io.h> +#define IO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_FCNTL_H +#ifndef FCNTL_H_INCLUDED +#include <fcntl.h> +#define FCNTL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_OPENSSL_RAND_H +#ifndef OPENSSL_RAND_H_INCLUDED +#include <openssl/rand.h> +#define OPENSSL_RAND_H_INCLUDED 1 +#endif +#endif + +#include "dk4types.h" +#include "dk4const.h" +#include "dk4mem.h" +#include "dk4mema.h" +#include "dk4memrs.h" +#include "dk4strd.h" +#include "dk4app.h" +#include "dk4aopt.h" +#include "dk4fput.h" +#include "dk4vers.h" +#include "dk4maiddsz.h" +#include "dk4maasz.h" +#include "dk4mpl.h" +#include "dk4svbufa.h" + + + + + +#line 97 "dk-pwgen.ctr" + + + +/** Output mode. +*/ +enum { + /** Create normal user password. + */ + DK_PWGEN_MODE_NORMAL = 0 , + + /** Create hard password. + */ + DK_PWGEN_MODE_HARD , + + /** Create binary data. + */ + DK_PWGEN_MODE_BINARY , + + /** Create hexadecimal key, use + lower case a to f. + */ + DK_PWGEN_MODE_HEX_LOWER , + + /** Create hexadecimal key, use + upper case A to F. + */ + DK_PWGEN_MODE_HEX_UPPER , + + /** Create numeric PIN. + */ + DK_PWGEN_MODE_PIN +}; + + +/** Constant texts used by program, not localized. +*/ +static const dkChar * const dk_pwgen_kwnl[] = { +/* 0 */ +dkT("dktools"), + +/* 1 */ +dkT("dk-pwgen.txt"), + +/* 2 */ +dkT("dk-pwgen.str"), + +/* 3 */ +dkT("0123456789abcdef"), + +/* 4 */ +dkT("0123456789ABCDEF"), + +/* 5 */ +dkT("0123456789"), + +/* 6 */ +dkT("-_.:,;<>|#'+*~@^!\"$%&/()=?`{[]}"), + +/* 7 */ +dkT("rand.egd.name"), + +/* 8 */ +dkT("verbose"), + +NULL + + +#line 167 "dk-pwgen.ctr" +}; + + + +static const dkChar * const dk_pwgen_help_text[] = { +dkT(""), +dkT("Generate passwords, PINs and hexadecimal keys"), +dkT(""), +dkT("dk-pwgen [<options>]"), +dkT(""), +dkT("Options:"), +dkT("-h\t\t--hard\t\t\tCreate hard password instead of normal."), +dkT("-b\t\t--binary\t\tCreate binary random data"), +dkT("\t\t\t\t\t(not on Windows)."), +dkT("-p\t\t--pin\t\t\tCreate PIN number."), +dkT("-x\t\t--hex\t\t\tCreate hexadecimal key, use `a'...`f'."), +dkT("-X\t\t--Hex\t\t\tCreate hexadecimal key, use `A'...`F'."), +dkT("-l <range>\t--length=<range>\tLength, i.e. ``8-10''."), +dkT("-u <range>\t--upper-case=<range>\tNumber of uppercase chars in passwords."), +dkT("-d <range>\t--digits=<range>\tNumber of digits in passwords."), +dkT("-s <range>\t--special=<range>\tNumber of special chars in passwords."), +dkT("-n\t\t--no-newline\t\tSuppress newline after output."), +dkT("\t\t--verbose\t\tShow error message on SIGPIPE."), +dkT(""), +dkT("\t\t--help\t\t\tShow this short help text."), +dkT("\t\t--manual\t\t*** SHOW FULL MANUAL. ***"), +dkT("\t\t--version\t\tShow version information."), +dkT("\t\t--license\t\tShow license information."), +dkT(""), +dkT("http://dktools.sourceforge.net"), +dkT(""), +NULL + + +#line 200 "dk-pwgen.ctr" +}; + + + +static const dkChar * const dk_pwgen_license_text[] = { +dkT("This software uses code from the following projects, either directly or as"), +dkT("a library:"), +dkT(""), +dkT("dktools\t\tDirk Krause's tools and libraries."), +dkT("\t\tSee http://dktools.sourceforge.net/ for more information."), +#if DK4_HAVE_ZLIB_H +dkT(""), +dkT("zlib\t\tData compression library."), +dkT("\t\tSee http://www.zlib.net/ for more information."), +#endif +#if DK4_HAVE_BZLIB_H +dkT(""), +dkT("bzip2\t\tData compression program and library."), +dkT("\t\tSee http://www.bzip.org/ for more information."), +#endif +#if DK4_HAVE_OPENSSL_RAND_H +dkT(""), +dkT("OpenSSL\t\tCryptographic toolkit, used to build file checksums here."), +dkT("\t\tSee http://www.openssl.org/ for more information."), +dkT(""), +dkT("This product includes software developed by the OpenSSL Project for use in"), +dkT("the OpenSSL Toolkit (http://www.openssl.org/)."), +dkT("This product includes cryptographic software written by"), +dkT("Eric Young (eay@cryptsoft.com)."), +dkT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."), +#endif +dkT(""), +dkT("All the licenses below apply to the program."), +dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"), +dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"), +dkT("homepages of the used libraries for additional information and/or updated"), +dkT("license terms."), +dkT(""), +dkT(""), +dkT("DK tools and libraries license"), +dkT("=============================="), +dkT("Copyright (c) 2015-2016, Dirk Krause"), +dkT("All rights reserved."), +dkT(""), +dkT("Redistribution and use in source and binary forms, with or without"), +dkT("modification, are permitted provided that the following conditions are met:"), +dkT(""), +dkT("* Redistributions of source code must retain the above copyright notice,"), +dkT(" this list of conditions and the following disclaimer."), +dkT("* Redistributions in binary form must reproduce the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer in the"), +dkT(" documentation and/or other materials provided with the distribution."), +dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"), +dkT(" used to endorse or promote products derived from this software without"), +dkT(" specific prior written permission."), +dkT(""), +dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""), +dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), +dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), +dkT("ARE DISCLAIMED."), +dkT(""), +dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"), +dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"), +dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"), +dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"), +dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"), +dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"), +dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."), +#if DK4_HAVE_ZLIB_H +dkT(""), +dkT(""), +dkT("Zlib license"), +dkT("============"), +dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"), +dkT(""), +dkT("This software is provided 'as-is', without any express or implied"), +dkT("warranty. In no event will the authors be held liable for any damages"), +dkT("arising from the use of this software."), +dkT(""), +dkT("Permission is granted to anyone to use this software for any purpose,"), +dkT("including commercial applications, and to alter it and redistribute it"), +dkT("freely, subject to the following restrictions:"), +dkT(""), +dkT("1. The origin of this software must not be misrepresented; you must not"), +dkT(" claim that you wrote the original software. If you use this software"), +dkT(" in a product, an acknowledgment in the product documentation would be"), +dkT(" appreciated but is not required."), +dkT("2. Altered source versions must be plainly marked as such, and must not be"), +dkT(" misrepresented as being the original software."), +dkT("3. This notice may not be removed or altered from any source distribution."), +dkT(""), +dkT("Jean-loup Gailly Mark Adler"), +dkT("jloup@gzip.org madler@alumni.caltech.edu"), +#endif +#if DK4_HAVE_BZLIB_H +dkT(""), +dkT(""), +dkT("Bzip2 and libbzip2 library license"), +dkT("=================================="), +dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"), +dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"), +dkT("rights reserved."), +dkT(""), +dkT("Redistribution and use in source and binary forms, with or without"), +dkT("modification, are permitted provided that the following conditions"), +dkT("are met:"), +dkT(""), +dkT("1. Redistributions of source code must retain the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer."), +dkT(""), +dkT("2. The origin of this software must not be misrepresented; you must "), +dkT(" not claim that you wrote the original software. If you use this "), +dkT(" software in a product, an acknowledgment in the product "), +dkT(" documentation would be appreciated but is not required."), +dkT(""), +dkT("3. Altered source versions must be plainly marked as such, and must"), +dkT(" not be misrepresented as being the original software."), +dkT(""), +dkT("4. The name of the author may not be used to endorse or promote "), +dkT(" products derived from this software without specific prior written "), +dkT(" permission."), +dkT(""), +dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"), +dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"), +dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), +dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"), +dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"), +dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"), +dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"), +dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"), +dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"), +dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"), +dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."), +dkT(""), +dkT("Julian Seward, jseward@bzip.org"), +dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"), +#endif +#if DK4_HAVE_OPENSSL_RAND_H +dkT(""), +dkT(""), +dkT("OpenSSL license"), +dkT("==============="), +dkT(""), +dkT("LICENSE ISSUES"), +dkT("--------------"), +dkT(""), +dkT("The OpenSSL toolkit stays under a dual license, i.e. both the conditions of"), +dkT("the OpenSSL License and the original SSLeay license apply to the toolkit."), +dkT("See below for the actual license texts. Actually both licenses are BSD-style"), +dkT("Open Source licenses. In case of any license issues related to OpenSSL"), +dkT("please contact openssl-core@openssl.org."), +dkT(""), +dkT("OpenSSL License"), +dkT("---------------"), +dkT(""), +dkT("Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved."), +dkT(""), +dkT("Redistribution and use in source and binary forms, with or without"), +dkT("modification, are permitted provided that the following conditions"), +dkT("are met:"), +dkT(""), +dkT("1. Redistributions of source code must retain the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer. "), +dkT(""), +dkT("2. Redistributions in binary form must reproduce the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer in"), +dkT(" the documentation and/or other materials provided with the"), +dkT(" distribution."), +dkT(""), +dkT("3. All advertising materials mentioning features or use of this"), +dkT(" software must display the following acknowledgment:"), +dkT(" \"This product includes software developed by the OpenSSL Project"), +dkT(" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\""), +dkT(""), +dkT("4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to"), +dkT(" endorse or promote products derived from this software without"), +dkT(" prior written permission. For written permission, please contact"), +dkT(" openssl-core@openssl.org."), +dkT(""), +dkT("5. Products derived from this software may not be called \"OpenSSL\""), +dkT(" nor may \"OpenSSL\" appear in their names without prior written"), +dkT(" permission of the OpenSSL Project."), +dkT(""), +dkT("6. Redistributions of any form whatsoever must retain the following"), +dkT(" acknowledgment:"), +dkT(" \"This product includes software developed by the OpenSSL Project"), +dkT(" for use in the OpenSSL Toolkit (http://www.openssl.org/)\""), +dkT(""), +dkT("THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY"), +dkT("EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), +dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR"), +dkT("PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR"), +dkT("ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,"), +dkT("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT"), +dkT("NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"), +dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"), +dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"), +dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"), +dkT("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED"), +dkT("OF THE POSSIBILITY OF SUCH DAMAGE."), +dkT(""), +dkT("This product includes cryptographic software written by Eric Young"), +dkT("(eay@cryptsoft.com). This product includes software written by Tim"), +dkT("Hudson (tjh@cryptsoft.com)."), +dkT(""), +dkT(""), +dkT("Original SSLeay License"), +dkT("-----------------------"), +dkT(""), +dkT("Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)"), +dkT("All rights reserved."), +dkT(""), +dkT("This package is an SSL implementation written"), +dkT("by Eric Young (eay@cryptsoft.com)."), +dkT("The implementation was written so as to conform with Netscapes SSL."), +dkT(""), +dkT("This library is free for commercial and non-commercial use as long as"), +dkT("the following conditions are aheared to. The following conditions"), +dkT("apply to all code found in this distribution, be it the RC4, RSA,"), +dkT("lhash, DES, etc., code; not just the SSL code. The SSL documentation"), +dkT("included with this distribution is covered by the same copyright terms"), +dkT("except that the holder is Tim Hudson (tjh@cryptsoft.com)."), +dkT(""), +dkT("Copyright remains Eric Young's, and as such any Copyright notices in"), +dkT("the code are not to be removed."), +dkT("If this package is used in a product, Eric Young should be given attribution"), +dkT("as the author of the parts of the library used."), +dkT("This can be in the form of a textual message at program startup or"), +dkT("in documentation (online or textual) provided with the package."), +dkT(""), +dkT("Redistribution and use in source and binary forms, with or without"), +dkT("modification, are permitted provided that the following conditions"), +dkT("are met:"), +dkT("1. Redistributions of source code must retain the copyright"), +dkT(" notice, this list of conditions and the following disclaimer."), +dkT("2. Redistributions in binary form must reproduce the above copyright"), +dkT(" notice, this list of conditions and the following disclaimer in the"), +dkT(" documentation and/or other materials provided with the distribution."), +dkT("3. All advertising materials mentioning features or use of this software"), +dkT(" must display the following acknowledgement:"), +dkT(" \"This product includes cryptographic software written by"), +dkT(" Eric Young (eay@cryptsoft.com)\""), +dkT(" The word 'cryptographic' can be left out if the rouines from the library"), +dkT(" being used are not cryptographic related :-)."), +dkT("4. If you include any Windows specific code (or a derivative thereof) from "), +dkT(" the apps directory (application code) you must include an acknowledgement:"), +dkT(" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\""), +dkT(""), +dkT("THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND"), +dkT("ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"), +dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"), +dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE"), +dkT("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"), +dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"), +dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"), +dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"), +dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"), +dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"), +dkT("SUCH DAMAGE."), +dkT(""), +dkT("The licence and distribution terms for any publically available version or"), +dkT("derivative of this code cannot be changed. i.e. this code cannot simply be"), +dkT("copied and put under another distribution licence"), +dkT("[including the GNU Public Licence.]"), +dkT(""), +#endif +dkT(""), +NULL + + +#line 469 "dk-pwgen.ctr" +}; + + + +static const dkChar * const dk_pwgen_kw_def[] = { +/* 0 */ +dkT("OpenSSL PRNG not available!"), + +/* 1 */ +dkT("Failed to set up signal handlers!"), + +/* 2 */ +dkT("Failed to restore signal handlers!"), + +/* 3 */ +dkT("Numeric overflow while reading a size number!"), + +/* 4 */ +dkT("Not a size specification: \""), + +/* 5 */ +dkT("\"!"), + +/* 6 */ +dkT("Failed to retrieve size from text: \""), + +/* 7 */ +dkT("\"!"), + +/* 8 */ +dkT("Options -h, -x, -X, and -p are mutually exclusive!"), + +/* 9 */ +dkT("Option -u ignored for this output type!"), + +/* 10 */ +dkT("Option -d ignored for this output type!"), + +/* 11 */ +dkT("Option -s ignored for this output type!"), + +/* 12 */ +dkT("Conflicting ranges for -l and -u/-d/-s!"), + +/* 13 */ +dkT("Numeric overflow in password length calculation!"), + +/* 14 */ +dkT("Failed to obtain random data from cryptographic context!"), + +/* 15 */ +dkT("Failed to acquire cryptographic context!"), + +/* 16 */ +dkT("Failed to open /dev/random and /dev/urandom devices!"), + +/* 17 */ +dkT("Failed to obtain random data!"), + +/* 18 */ +dkT("Failed to seed OpenSSL PRNG!"), + +/* 19 */ +dkT("Aborted by SIGTERM signal!"), + +/* 20 */ +dkT("Aborted by SIGINT signal!"), + +/* 21 */ +dkT("Aborted by SIGPIPE signal!"), + +/* 22 */ +dkT("Write attempt to standard output failed!"), + +/* 23 */ +dkT("Seeding PRNG using OpenSSL builtin functions."), + +/* 24 */ +dkT("Seeding PRNG from EGD socket."), + +/* 25 */ +dkT("Seeding PRNG from Windows cryptographic context."), + +/* 26 */ +dkT("Seeding PRNG from screen contents."), + +/* 27 */ +dkT("Seeding PRNG from /dev/random or /dev/urandom device."), + +/* 28 */ +dkT("Seeding PRNG from EGD socket specified by preference."), + +/* 29 */ +dkT("Options -b, -h, -x, -X, and -p are mutually exclusive!"), + +/* 30 */ +dkT("Failed to reset used memory!"), + +/* 31 */ +dkT("The -b option is not supported on Windows!"), + +NULL + + +#line 586 "dk-pwgen.ctr" +}; + + + +/** Options understood by program. +*/ +static const dk4_option_specification_t dk_pwgen_options[] = { + { dkT('h'), dkT("hard"), DK4_OPT_ARG_NONE }, + { dkT('b'), dkT("binary"), DK4_OPT_ARG_NONE }, + { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE }, + { dkT('X'), dkT("Hex"), DK4_OPT_ARG_NONE }, + { dkT('p'), dkT("pin"), DK4_OPT_ARG_NONE }, + { dkT('l'), dkT("length"), DK4_OPT_ARG_STRING }, + { dkT('u'), dkT("upper-case"), DK4_OPT_ARG_STRING }, + { dkT('d'), dkT("digits"), DK4_OPT_ARG_STRING }, + { dkT('s'), dkT("special"), DK4_OPT_ARG_STRING }, + { dkT('n'), dkT("no-newline"), DK4_OPT_ARG_NONE }, + { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE } +}; + + + +#ifndef BUFSIZ +#define BUFSIZ 8192 +#endif + + +/** Use an explicitly specified buffer for stdout operations + so we can securely reset the memory before exiting. +*/ +static char stdout_buffer[BUFSIZ]; + + + +/** Use an explicitly specified buffer when reading seed file + so we can securely reset the memory before exiting. +*/ +static char seed_file_buf[BUFSIZ]; + + + +/** Localized version if available, otherwise default texts. +*/ +static const dkChar * const *dk_pwgen_msg = dk_pwgen_kw_def; + + + +/** Application structure. +*/ +static dk4_app_t *app = NULL; + + + +/** Number of elements in dk_pwgen_msg array. +*/ +static size_t dk_pwgen_sz_msg = +sizeof(dk_pwgen_kw_def)/sizeof(DK4_PCDKCHAR) - 1; + + +/** Number of elements in dk_pwgen_options array. +*/ +static const size_t dk_pwgen_sz_options = +sizeof(dk_pwgen_options)/sizeof(dk4_option_specification_t); + + + +/** Minimum output length. +*/ +static size_t length_min = 8; + + + +/** Maximum output length. +*/ +static size_t length_max = 10; + + + +/** Output length to produce. +*/ +static size_t length = 8; + + + +/** Minimum number of upper case characters. +*/ +static size_t upper_min = 1; + + + +/** Maximum number of upper case characters. +*/ +static size_t upper_max = 2; + + + +/** Number of upper case characters to produce. +*/ +static size_t upper = 1; + + + +/** Minimum number of digits. +*/ +static size_t digit_min = 1; + + + +/** Maximum number of digits. +*/ +static size_t digit_max = 2; + + + +/** Number of digits to produce. +*/ +static size_t digits = 1; + + + +/** Minimum number of special characters. +*/ +static size_t special_min = 1; + + + +/** Maximum number of special characters. +*/ +static size_t special_max = 2; + + + +/** Number of special characters to produce. +*/ +static size_t specials = 1; + + + +/** Flag: Errors occured while writing to stdout. +*/ +static int output_error = 0; + + + +/** Flag: Verbose output (report SIGPIPE). +*/ +static int verbose = 1; + + + +/** Exit status code. +*/ +static int exval = EXIT_FAILURE; + + + +/** Output type to produce. +*/ +static int output_type = DK_PWGEN_MODE_NORMAL; + + + +#if DK4_HAVE_OPENSSL_RAND_H + + + +#ifdef SIGPIPE +/** Indicator: SIGPIPE signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_pipe = 0; +#endif + +/** Indicator: SIGINT signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_int = 0; + +/** Indicator: SIGTERM signal received. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t sig_had_term = 0; + + + +/** Pass a volatile pointer to an atomic integer. + This function is necessary as some compilers mis-optimize + direct access to volatile variables (at least if you believe + one of the coding standards). + @param ptr Address of atomic integer variable. + @return The unmodified pointer. +*/ +static +DK4_VOLATILE +dk4_sig_atomic_t * +sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr) +{ + return ptr; +} + + + +#ifdef SIGPIPE +/** Handler for SIGPIPE signal. + @param signo Signal number (always SIGPIPE, ignored). +*/ +static +void +sig_handler_pipe(int signo) +{ + *sig_pass_pointer(&sig_had_pipe) = 1; +} +#endif + +/** Handler for SIGINT signal. + @param signo Signal number (always SIGINT, ignored). +*/ +static +void +sig_handler_int(int signo) +{ + *sig_pass_pointer(&sig_had_int) = 1; +} + +/** Handler for SIGTERM signal. + @param signo Signal number (always SIGTERM, ignored). +*/ +static +void +sig_handler_term(int signo) +{ + *sig_pass_pointer(&sig_had_term) = 1; +} + +/** Read value from volatile atomic type. + This function is necessary as some compilers mis-optimize + direct access to volatile variables (at least if you believe + one of the coding standards). + @param ap Pointer to volatile atomic variable. + @return Contents of the variable. +*/ +static +dk4_sig_atomic_t +sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap) +{ + return (*ap); +} + +/** Check whether we can continue or if a signal was received. + @param check_pipe Flag: Check for occured SIGPIPE signal too. + @return 1 if the program can continue, 0 if a signal was received. +*/ +static +int +sig_can_continue(int check_pipe) +{ + int back = 1; +#ifdef SIGPIPE + if (0 != check_pipe) { + if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; } + } +#endif + if (0 != sig_read_atomic(&sig_had_int )) { back = 0; } + if (0 != sig_read_atomic(&sig_had_term)) { back = 0; } + return back; +} + + + +/** Check whether we can continue. + @return 1 for yes, 0 for no. +*/ +static +int +dk_pwgen_can_continue(void) +{ + int back = 1; + if (0 == sig_can_continue(1)) { + back = 0; + } + return back; +} + + + +/** Read range from text to size_t variables. + @param minptr Address of minimum variable. + @param maxptr Address of maximum variable. + @param buf Buffer containing the text. + @return 1 on success, 0 on error. +*/ +static +int +dk_pwgen_opt_range(size_t *minptr, size_t *maxptr, dkChar option) +{ + dkChar buf[32*sizeof(dk4_um_t)]; + dk4_er_t er; + const dkChar *endptr; + dkChar *p1; + size_t val; + int res; + int rdf = 0; + int back = 0; + int passno = 0; + + +#line 894 "dk-pwgen.ctr" + if (0 != dk4app_opt_is_set_long(app, dk_pwgen_kwnl[8], NULL)) { + verbose = 1; + } + if (0 != dk4app_opt_is_set_short(app, option, NULL)) { + res = dk4app_opt_get_string_short( + buf, DK4_SIZEOF(buf,dkChar), app, option, NULL + ); + if (0 != res) { + +#line 902 "dk-pwgen.ctr" + p1 = dk4str_chr(buf, dkT('-')); + if (NULL != p1) { + +#line 904 "dk-pwgen.ctr" + *(p1++) = dkT('\0'); + p1 = dk4str_start(p1, NULL); + } else { + +#line 907 "dk-pwgen.ctr" + } + val = 0; + endptr = NULL; + dk4error_init(&er); + if (0 != dk4ma_input_dk_dec_size_t(&val, buf, &endptr, 1, &er)) { + *minptr = val; + *maxptr = val; + back = 1; + if (NULL != p1) { + +#line 916 "dk-pwgen.ctr" + passno = 1; + back = 0; + val = 0; + endptr = NULL; + if (0 != dk4ma_input_dk_dec_size_t(&val, p1, &endptr, 1, &er)) { + *maxptr = val; + back = 1; + if (*maxptr < *minptr) { + val = *maxptr; + *maxptr = *minptr; + *minptr = val; + } + } else { + +#line 929 "dk-pwgen.ctr" + /* ERROR: Failed to read size */ + rdf = 1; + } + } + } else { + +#line 934 "dk-pwgen.ctr" + /* ERROR: Failed to read size */ + rdf = 1; + } + } else { + +#line 938 "dk-pwgen.ctr" + /* ERROR: Failed to obtain option argument, probably bug */ + } + } else { + +#line 941 "dk-pwgen.ctr" + back = 1; + } + if ((0 == back) && (0 != rdf)) { + switch (er.ec) { + case DK4_E_MATH_OVERFLOW : { + +#line 946 "dk-pwgen.ctr" + /* ERROR: Numeric overflow while reading number */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 3); + } break; + case DK4_E_SYNTAX : { + +#line 950 "dk-pwgen.ctr" + /* ERROR: Not a size specification */ + dk4app_log_3( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 4, 5, + ((0 == passno) ? buf : p1) + ); + } break; + default: { + +#line 957 "dk-pwgen.ctr" + /* ERROR: Failed to read size */ + dk4app_log_3( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 6, 7, + ((0 == passno) ? buf : p1) + ); + } break; + } + } + +#line 965 "dk-pwgen.ctr" + return back; +} + + + +/** Process command line options. + @return 1 on success, 0 on error (invalid option combination). +*/ +static +int +dk_pwgen_check_options(void) +{ + dk4_er_t er; + size_t val; + int back = 0; + + +#line 981 "dk-pwgen.ctr" + + if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) { + output_type = DK_PWGEN_MODE_BINARY; + if ( + (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) + ) + { + /* ERROR: Options -b, -h, -x, -X and -p are mutually exclusive! */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 29); + goto finished; + } + else + { + back = 1; + } + } else { + if (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL)) { + output_type = DK_PWGEN_MODE_HARD; + if ( + (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) + ) + { + /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8); + goto finished; + } + else + { + back = 1; + } + } else { + if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) { + output_type = DK_PWGEN_MODE_HEX_LOWER; + if ( + (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) + || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) + ) + { + /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8); + goto finished; + } + else + { + back = 1; + } + } else { + if (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) { + output_type = DK_PWGEN_MODE_HEX_UPPER; + if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) { + /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8); + goto finished; + } else { + back = 1; + } + } else { + if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) { + output_type = DK_PWGEN_MODE_PIN; + } + back = 1; + } + } + } + } + if (1 == back) { + if (0 == dk_pwgen_opt_range(&length_min, &length_max, dkT('l'))) { + back = 0; + } + if (1 == back) { + switch (output_type) { + case DK_PWGEN_MODE_HARD : + case DK_PWGEN_MODE_HEX_LOWER : + case DK_PWGEN_MODE_HEX_UPPER : + case DK_PWGEN_MODE_PIN : + { + if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) { + /* WARNING: Option ignored */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 9); + } + if (0 != dk4app_opt_is_set_short(app, dkT('d'), NULL)) { + /* WARNING: Option ignored */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 10); + } + if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) { + /* WARNING: Option ignored */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 11); + } + } break; + default : { + if (0 != dk_pwgen_opt_range(&upper_min, &upper_max, dkT('u'))) { + if (0 != dk_pwgen_opt_range(&digit_min, &digit_max, dkT('d'))) { + if (0 != dk_pwgen_opt_range(&special_min, &special_max, dkT('s'))) + { + dk4error_init(&er); + val = dk4ma_size_t_add(upper_max, digit_max, &er); + val = dk4ma_size_t_add(val, special_max, &er); + if (DK4_E_NONE == er.ec) { + if (val > length_min) { + back = 0; + /* ERROR: Illegal range combination */ + dk4app_log_1( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12 + ); + } + } else { + /* ERROR: Numeric overflow in size calculation */ + dk4app_log_1( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 13 + ); + } + } else { + back = 0; + } + } else { + back = 0; + } + } else { + back = 0; + } + } break; + } + } + } + finished: + + +#line 1112 "dk-pwgen.ctr" + return back; +} + + + +/** Seed PRNG. + @return 1 on success, 0 on error (not enough seed data). +*/ +static +int +dk_pwgen_seed_prng(void) +{ +#if DK4_CHAR_SIZE == 1 + dkChar snb[DK4_MAX_PATH]; +#endif + char buffer[64]; + char *envptr; +#if DK4_ON_WINDOWS + HCRYPTPROV hcp; + BOOL res; +#else + FILE *fipo; + size_t rdb; +#endif + int cc; + int rounds = 0; + int back = 0; + int svbres = 0; + + +#line 1141 "dk-pwgen.ctr" + + /* Let OpenSSL library functions try to initialize. + */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 23); + if (1 == RAND_status()) { + back = 1; + goto finished; + } + +#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN + /* Attempt EGD socket if specified in environment. + */ + envptr = getenv("EGDSOCKET"); + if (NULL != envptr) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 24); + if (0 < RAND_egd(envptr)) { + if (1 == RAND_status()) { + back = 1; + goto finished; + } + } + } + + /* Attempt EGD socket defined by preference. + The RAND_egd() function accepts char, not dkChar. + */ +#if DK4_CHAR_SIZE == 1 + if (0 != dk4app_pref_get(snb,DK4_SIZEOF(snb,dkChar),app,dk_pwgen_kwnl[7],0)) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 28); + if (0 < RAND_egd(snb)) { + if (1 == RAND_status()) { + back = 1; + goto finished; + } + } + } +#endif +#endif + + /* Use platform specific mechanisms if available. + */ +#if DK4_ON_WINDOWS + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25); + res = CryptAcquireContext( + &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT + ); + if (res) { + cc = 1; + do { + if (0 != dk_pwgen_can_continue()) { + res = CryptGenRandom(hcp, (DWORD)sizeof(buffer), buffer); + if (res) { + RAND_seed(buffer, sizeof(buffer)); + if (1 == RAND_status()) { + cc = 0; + back = 1; + } else { + rounds++; + } + } else { + cc = -1; + /* ERROR: Failed to obtain random bytes from crypto context */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 14); + } + } else { + cc = -1; + } + } while ((1 == cc) && (128 > rounds)); + CryptReleaseContext(hcp, (DWORD)0UL); + dk4mem_reset_secure(buffer, sizeof(buffer), NULL); + if (0 == back) { + if (0 != dk_pwgen_can_continue()) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25); + RAND_screen(); + if (1 == RAND_status()) { + back = 1; + } + } + } + } else { + /* ERROR: Failed to acquire crypto context */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 15); + } +#else + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 27); + fipo = fopen("/dev/random", "rb"); + if (NULL == fipo) { + fipo = fopen("/dev/urandom", "rb"); + } + if (NULL != fipo) { + dk4mem_reset(seed_file_buf, sizeof(seed_file_buf), NULL); + svbres = dk4setvbuf( + fipo, DK4_FILE_FULL_BUFFERING, seed_file_buf, sizeof(seed_file_buf), NULL + ); + if (0 != svbres) { + cc = 1; + do { + if (0 != dk_pwgen_can_continue()) { + rdb = fread(buffer, 1, sizeof(buffer), fipo); + if (0 < rdb) { + RAND_seed(buffer, rdb); + if (1 == RAND_status()) { + cc = 0; + back = 1; + } else { + rounds++; + } + } else { + cc = -1; + } + } else { + cc = -1; + } + } while ((1 == cc) && (128 > rounds)); + } else { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16); + } + fclose(fipo); + dk4mem_reset_secure(seed_file_buf, sizeof(seed_file_buf), NULL); + dk4mem_reset_secure(buffer, sizeof(buffer), NULL); + } else { + /* ERROR: Failed to open both /dev/random and /dev/urandom */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16); + } +#endif + + finished: + + +#line 1269 "dk-pwgen.ctr" + return back; +} + + + +/** Find a random number in a given range. + @param dptr Address of destination variable. + @param min Minimum value. + @param max Maximum value. + @return 1 on success, 0 on error. +*/ +static +int +dk_pwgen_value_in_range(size_t *dptr, size_t min, size_t max) +{ + size_t width; + size_t rval; + int back = 0; + + +#line 1288 "dk-pwgen.ctr" + if (max > min) { + width = max - min; + if (0 != (width + 1)) { width++ ; } + if (0 < RAND_bytes((unsigned char *)(&rval), (int)sizeof(rval))) { + + +#line 1293 "dk-pwgen.ctr" + *dptr = min + (rval % width); + back = 1; + } else { + /* ERROR: Failed to obtain random bytes */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + } else { + *dptr = min; + back = 1; + } + + +#line 1304 "dk-pwgen.ctr" + return back; +} + + + +/** Create hexadecimal key and write to standard output. + @param upper Flag: Use upper case `a' to `f'. +*/ +static +void +dk_pwgen_output_hex(int upper) +{ + unsigned char buf[8]; /* Buffer for 8 random bytes */ + size_t i; /* Index of current output character */ + size_t bi; /* Index in buffer 0 to 7 */ + size_t j; /* Index in hexademical digits string */ + int cc; /* Flag: Can continue 1=yes,0=no,-1=abort */ + dkChar dc; /* Current character to write */ + + +#line 1323 "dk-pwgen.ctr" + cc = 1; + i = 0; + bi = 0; + do { + if (0 != dk_pwgen_can_continue()) { + if (i < length) { + + + + if (0 == (i % 16)) { + bi = 0; + if (0 < RAND_bytes(buf, (int)sizeof(buf))) { + cc = 1; + } else { + cc = -1; + exval = EXIT_FAILURE; + /* ERROR: Random */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + } + if (1 == cc) { + j = (size_t)(buf[bi / 2]); + j = 0x00FFU & j; + if (0 == (i % 2)) { + j = j >> 4; + } + j &= 0x000FU; + dc = (dk_pwgen_kwnl[(0 != upper) ? 4 : 3])[j]; + if (0 == dk4fputc(dc, stdout, NULL)) { output_error = 1; cc = -1; } + } + i++; bi++; + } else { + cc = 0; + } + } else { + cc = -1; + } + } while (1 == cc); + if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } + dc = dkT('\0'); j = 0; + if ((0 != j) || (dkT('\0') != dc)) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } + + +#line 1371 "dk-pwgen.ctr" +} + + + +/** Create hard password and write to standard output. +*/ +static +void +dk_pwgen_output_hard(void) +{ + dk4_um_t val; + size_t i; + int cc; + dkChar dc; + + i = 0; cc = 1; + do { + if (0 != dk_pwgen_can_continue()) { + if (i < length) { + if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) { + dc = (dkChar)33 + (dkChar)(val % (dk4_um_t)90U); + if (0 == dk4fputc(dc, stdout, NULL)) { + output_error = 1; + cc = -1; + } + } else { + cc = -1; + exval = EXIT_FAILURE; + /* ERROR: Random */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + i++; + } else { + cc = 0; + } + } else { + cc = -1; + } + } while (1 == cc); + val = (dk4_um_t)0UL; dc = dkT('\0'); + if ((val != (dk4_um_t)0UL) || (dc != dkT('\0'))) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } +} + + + +/** Create binary password and write to standard output. +*/ +static +void +dk_pwgen_output_binary(void) +{ +#if !DK4_ON_WINDOWS + char buf[256]; + size_t i; + size_t remaining; + size_t wrb; + int cc; +#endif + +#if DK4_ON_WINDOWS + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 31); + exval = EXIT_FAILURE; +#else + remaining = length; + cc = 1; + do { + if (0 != dk_pwgen_can_continue()) { + i = sizeof(buf); + if (remaining < i) { i = remaining; } + if (0 == i) { + cc = 0; + } else { + if (0 < RAND_bytes((unsigned char *)buf, (int)i)) { + wrb = fwrite(buf, 1, i, stdout); + if (i == wrb) { + if (i >= remaining) { + cc = 0; + } else { + remaining = remaining - i; + } + } else { + cc = -1; + exval = EXIT_FAILURE; + output_error = 1; + } + } else { + cc = -1; + exval = EXIT_FAILURE; + /* ERROR: Random */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + } + } else { + cc = -1; + } + } while ((1 == cc) && (0 < remaining)); + if (0 != fflush(stdout)) { + exval = EXIT_FAILURE; + output_error = 1; + } + if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } +#endif +} + + +/** Create numeric PIN and write to standard output. +*/ +static +void +dk_pwgen_output_pin(void) +{ + dk4_um_t val; + size_t i; + int cc; + dkChar dc; + + i = 0; cc = 1; + do { + if (0 != dk_pwgen_can_continue()) { + if (i < length) { + if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) { + dc = dkT('0') + (dkChar)(val % (dk4_um_t)10U); + if (0 == dk4fputc(dc, stdout, NULL)) { + output_error = 1; + cc = -1; + } + } else { + cc = -1; + exval = EXIT_FAILURE; + /* ERROR: Random */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + i++; + } else { + cc = 0; + } + } else { + cc = -1; + } + } while (1 == cc); + dc = dkT('\0'); + if (dc != dkT('\0')) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } +} + + + +/** Create normal password and write to standard output. +*/ +static +void +dk_pwgen_output_normal(void) +{ + char *ti = NULL; /* Cells */ + dk4_um_t val; /* Value */ + size_t avail; /* Number of unused cells */ + size_t curel; /* Current element within group */ + size_t ind_to_set; /* Index of unused cell to set */ + size_t i; /* Traverse all cells */ + size_t max; /* Number of elements within pass */ + size_t speclen; /* Length of string containing special */ + int passno; /* Current pass */ + int cc; /* Flag: No error yet, can continue */ + int res; /* Operation result */ + dkChar dc; /* Character to write */ + char ic; /* Indicator character */ + + ti = dk4mem_new_app(char,length,app); + if (NULL != ti) { + +#line 1548 "dk-pwgen.ctr" + DK4_MEMRES(ti, length); + cc = 1; + if (0 == dk_pwgen_value_in_range(&upper, upper_min, upper_max)) { + cc = 0; + } + if (0 == dk_pwgen_value_in_range(&digits, digit_min, digit_max)) { + cc = 0; + } + if (0 == dk_pwgen_value_in_range(&specials, special_min, special_max)) { + cc = 0; + } + if (1 == cc) { + passno = 0; + avail = length; + while (3 > passno) { + +#line 1563 "dk-pwgen.ctr" + switch (passno) { + case 2 : { + max = specials; + ic = 's'; + } break; + case 1 : { + max = digits; + ic = 'd'; + } break; + default : { + max = upper; + ic = 'u'; + } break; + } + curel = 0; + while (curel < max) { + + +#line 1580 "dk-pwgen.ctr" + if (0 != dk_pwgen_can_continue()) { + res = RAND_bytes( + (unsigned char *)(&ind_to_set), (int)sizeof(size_t) + ); + if (0 < res) { + if (0 < avail) { + ind_to_set = ind_to_set % avail; + + +#line 1588 "dk-pwgen.ctr" + res = 0; + i = 0; + while (i < length) { + + +#line 1592 "dk-pwgen.ctr" + if ('\0' == ti[i]) { + if (0 == ind_to_set) { + + +#line 1595 "dk-pwgen.ctr" + res = 1; + ti[i] = ic; + i = length - 1; + avail--; + } else { + ind_to_set--; + } + } else { + +#line 1603 "dk-pwgen.ctr" + } + i++; + } + curel++; + if (0 == res) { + +#line 1608 "dk-pwgen.ctr" + /* No free cell found */ + curel = max; passno = 3; cc = 0; + dk4app_log_1( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12 + ); + } + } else { + /* No more cells available */ + curel = max; passno = 3; cc = 0; + dk4app_log_1( + app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12 + ); + } + } else { + /* ERROR: Random data */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + curel = max; passno = 3; cc = 0; + } + } else { + curel = max; passno = 3; cc = 0; + } + } + passno++; + if (0 == dk_pwgen_can_continue()) { passno = 3; } + } + if ((1 == cc) && (0 != dk_pwgen_can_continue())) { + +#line 1634 "dk-pwgen.ctr" + i = 0; + speclen = dk4str_len(dk_pwgen_kwnl[6]); + + +#line 1637 "dk-pwgen.ctr" + while (i < length) { + + +#line 1639 "dk-pwgen.ctr" + if (0 != dk_pwgen_can_continue()) { + res = RAND_bytes( + (unsigned char *)(&val), (int)sizeof(dk4_um_t) + ); + if (0 < res) { + + +#line 1645 "dk-pwgen.ctr" + switch (ti[i]) { + case 's': { + val = val % (dk4_um_t)speclen; + + +#line 1649 "dk-pwgen.ctr" + dc = (dk_pwgen_kwnl[6])[(size_t)val]; + } break; + case 'd': { + val = val % (dk4_um_t)10UL; + dc = dkT('0') + (dkChar)val; + } break; + case 'u': { + val = val % (dk4_um_t)26UL; + dc = dkT('A') + (dkChar)val; + } break; + default: { + val = val % (dk4_um_t)26UL; + dc = dkT('a') + (dkChar)val; + } break; + } + if (0 == dk4fputc(dc, stdout, NULL)) { + output_error = 1; + } + i++; + } else { + i = length; + exval = EXIT_FAILURE; + /* ERROR: Random */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17); + } + } else { + i = length; + } + } + } else { + exval = EXIT_FAILURE; + } + } else { + exval = EXIT_FAILURE; + /* Failed to obtain random */ + } + if (0 == dk4mem_reset_secure(ti, length, NULL)) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } + dk4mem_free(ti); + dc = dkT('\0'); + if (dc != dkT('\0')) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } + } else { + +#line 1696 "dk-pwgen.ctr" + exval = EXIT_FAILURE; + /* ERROR: Memory, already reported */ + } +} + + + +/** Create password, PIN or key and write to output. +*/ +static +void +dk_pwgen_produce_output(void) +{ + + +#line 1710 "dk-pwgen.ctr" + if (0 != dk_pwgen_value_in_range(&length, length_min, length_max)) { + exval = EXIT_SUCCESS; + switch (output_type) { + case DK_PWGEN_MODE_BINARY : { + +#line 1714 "dk-pwgen.ctr" + dk_pwgen_output_binary(); + } break; + case DK_PWGEN_MODE_HARD : { + +#line 1717 "dk-pwgen.ctr" + dk_pwgen_output_hard(); + } break; + case DK_PWGEN_MODE_HEX_LOWER : { + +#line 1720 "dk-pwgen.ctr" + dk_pwgen_output_hex(0); + } break; + case DK_PWGEN_MODE_HEX_UPPER : { + +#line 1723 "dk-pwgen.ctr" + dk_pwgen_output_hex(1); + } break; + case DK_PWGEN_MODE_PIN : { + +#line 1726 "dk-pwgen.ctr" + dk_pwgen_output_pin(); + } break; + default : { + +#line 1729 "dk-pwgen.ctr" + dk_pwgen_output_normal(); + } break; + } + if (0 == dk4app_opt_is_set_short(app, dkT('n'), NULL)) { + if (DK_PWGEN_MODE_BINARY != output_type) { + if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { + output_error = 1; + } + } + } + } + + +#line 1741 "dk-pwgen.ctr" +} + + + +/** Run normally with signal handlers installed. +*/ +static +void +dk_pwgen_normal_run(void) +{ + + +#line 1752 "dk-pwgen.ctr" + if (0 < dk_pwgen_check_options()) { + if (0 < dk_pwgen_seed_prng()) { + dk_pwgen_produce_output(); + } else { + /* ERROR: Failed to seed PRNG */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 18); + } + RAND_cleanup(); + } + + +#line 1762 "dk-pwgen.ctr" +} + + + + +#if DK4_HAVE_SIGACTION +/** Set signal handlers and run. +*/ +static +void +dk_pwgen_run_with_signal_handlers(void) +{ +#ifdef SIGPIPE + struct sigaction opipe; +#endif + struct sigaction oint; +#ifdef SIGPIPE + struct sigaction npipe; +#endif + struct sigaction nint; + struct sigaction oterm; + struct sigaction nterm; + int success = 0; + +#ifdef SIGPIPE + /* Set up signal handling for SIGPIPE. + */ + DK4_MEMRES(&npipe, sizeof(npipe)); + npipe.sa_handler = sig_handler_pipe; + npipe.sa_flags = 0; + if (0 != sigemptyset(&npipe.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto finished; + } + if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto finished; + } + if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { + /* ERROR: Failed to set up signal handler for SIGPIPE */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto finished; + } +#endif + + /* Set up signal handling for SIGINT. + */ + DK4_MEMRES(&nint, sizeof(nint)); + nint.sa_handler = sig_handler_int; + nint.sa_flags = 0; + if (0 != sigemptyset(&nint.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_pipe; + } + if (0 != sigaddset(&nint.sa_mask, SIGINT)) { + /* ERROR: Failed to set up masked signal set for SIGINT */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_pipe; + } + if (0 != sigaction(SIGINT, &nint, &oint)) { + /* ERROR: Failed to set up signal handler for SIGINT */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_pipe; + } + + /* Set up signal handling for SIGTERM + */ + DK4_MEMRES(&nterm, sizeof(nterm)); + nterm.sa_handler = sig_handler_term; + nterm.sa_flags = 0; + if (0 != sigemptyset(&nterm.sa_mask)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_int; + } + if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { + /* ERROR: Failed to set up masked signal set for SIGTERM */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_int; + } + if (0 != sigaction(SIGTERM, &nterm, &oterm)) { + /* ERROR: Failed to set up signal handler for SIGTERM */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1); + goto restore_old_int; + } + + success = 1; + dk_pwgen_normal_run(); + + /* Restore signal handling for SIGTERM. + */ + if (0 != sigaction(SIGTERM, &oterm, NULL)) { + /* ERROR: Failed to restore old SIGTERM settings */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2); + success = 0; + } + + /* Restore signal handling for SIGINT. + */ + restore_old_int: + if (0 != sigaction(SIGINT, &oint, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2); + success = 0; + } + +#ifdef SIGPIPE + /* Restore signal handling for SIGPIPE. + */ + restore_old_pipe: + if (0 != sigaction(SIGPIPE, &opipe, NULL)) { + /* ERROR: Failed to restore old SIGPIPE settings */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2); + success = 0; + } +#endif + + /* Set exit status code if error occured. + */ + finished: + if (0 == success) { exval = EXIT_FAILURE; } +} +#else +#if DK4_HAVE_SIGSET +/** Set signal handlers and run. +*/ +static +void +dk_pwgen_run_with_signal_handlers(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + +#ifdef SIGPIPE + oldpipe = sigset(SIGPIPE, sig_handler_pipe); +#endif + oldint = sigset(SIGINT, sig_handler_int); + oldterm = sigset(SIGTERM, sig_handler_term); + dk_pwgen_normal_run(); + sigset(SIGTERM, oldterm); + sigset(SIGINT, oldint); +#ifdef SIGPIPE + sigset(SIGPIPE, oldpipe); +#endif +} +#else +#if DK4_HAVE_SIGNAL +/** Set signal handlers and run. +*/ +static +void +dk_pwgen_run_with_signal_handlers(void) +{ +#ifdef SIGPIPE + dk4_sig_handler_t *oldpipe = NULL; +#endif + dk4_sig_handler_t *oldint = NULL; + dk4_sig_handler_t *oldterm = NULL; + +#ifdef SIGPIPE + oldpipe = signal(SIGPIPE, sig_handler_pipe); +#endif + oldint = signal(SIGINT, sig_handler_int); + oldterm = signal(SIGTERM, sig_handler_term); + dk_pwgen_normal_run(); + signal(SIGTERM, oldterm); + signal(SIGINT, oldint); +#ifdef SIGPIPE + signal(SIGPIPE, oldpipe); +#endif +} +#else +/** Set signal handlers and run. +*/ +static +void +dk_pwgen_run_with_signal_handlers(void) +{ + dk_pwgen_normal_run(); +} +#endif +#endif +#endif + +#endif +/* if DK4_HAVE_OPENSSL_RAND_H */ + + + +/** Main function. + @param argc Number of command line arguments. + @param argv Command line arguments array. + @return 0 on success, all other values indicate errors. +*/ +#if DK4_CHAR_SIZE > 1 +int wmain(int argc, wchar_t *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + int shp; + int pbso; /* Flag: Private buffer used for stdout */ + + pbso = dk4setvbuf( + stdout, DK4_FILE_LINE_BUFFERING, stdout_buffer, sizeof(stdout_buffer), NULL + ); + + +#line 1975 "dk-pwgen.ctr" + + +#line 1976 "dk-pwgen.ctr" + dk4fput_initialize_stdout(); + dk4fput_initialize_stderr(); + app = dk4app_open_cmd( + argc, argv, dk_pwgen_options, dk_pwgen_sz_options, + dk_pwgen_kwnl[0], DKT_VERSION_DK, + dk_pwgen_kwnl[1], dk_pwgen_help_text, dk_pwgen_license_text + ); + if (NULL != app) { + dk_pwgen_sz_msg = dk4app_string_table_size(dk_pwgen_kw_def); + dk_pwgen_msg = dk4app_string_table(app,dk_pwgen_kwnl[2],dk_pwgen_kw_def); + if (0 != dk4app_can_run_normally(app)) { +#if DK4_HAVE_OPENSSL_RAND_H + /* + Run. + */ + dk_pwgen_run_with_signal_handlers(); + /* + Report signals and output errors, if any. + */ + if (0 != sig_read_atomic(&sig_had_term)) { + /* ERROR: SIGTERM signal received */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 19); + exval = EXIT_FAILURE; + } + if (0 != sig_read_atomic(&sig_had_int )) { + /* ERROR: SIGINT signal received */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 20); + exval = EXIT_FAILURE; + } +#ifdef SIGPIPE + if (0 != sig_read_atomic(&sig_had_pipe)) { + /* ERROR: SIGPIPE signal received */ + if (0 != verbose) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 21); + } + exval = EXIT_FAILURE; + shp = 1; + } else { + shp = 0; + } +#else + shp = 0; +#endif + if ((0 == shp) && (0 != output_error)) { + /* ERROR: Failed to write to stdout */ + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 22); + exval = EXIT_FAILURE; + } +#else + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 0); +#endif + if (0 == pbso) { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } else { +#ifdef BUFSIZ + fflush(stdout); + if (0 == dk4mem_reset_secure(stdout_buffer,sizeof(stdout_buffer),NULL)) + { + dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30); + exval = EXIT_FAILURE; + } +#endif + } + } else { + if (0 != dk4app_help_version_license(app)) { + exval = EXIT_SUCCESS; + } + } + dk4app_close(app); + } else { + } + fflush(stdout); + fflush(stderr); + dk4fput_cleanup_stderr(); + dk4fput_cleanup_stdout(); + + +#line 2053 "dk-pwgen.ctr" + + +#line 2054 "dk-pwgen.ctr" + exit(exval); return exval; +} + |