├── .gitattributes ├── .gitignore ├── Config.in ├── LICENSE ├── Makefile ├── PeterPawn.asc ├── README.md ├── bin ├── .gitattributes ├── README.md ├── decoder.armv7l ├── decoder.armv7l.sig ├── decoder.i686 ├── decoder.i686.sig ├── decoder.mips ├── decoder.mips.sig ├── decoder.x86_64 └── decoder.x86_64.sig ├── decoder.mk ├── docs └── _config.yml ├── extras └── cryptedbin.sh ├── scripts ├── Makefile ├── crypto ├── decode_cryptedbinfile ├── decode_export ├── decode_secret ├── decode_secrets ├── device_password ├── password_from_device ├── privatekeypassword └── user_password └── src ├── .gitignore ├── Makefile ├── b32dec.c ├── b32dec.h ├── b32dec_usage.c ├── b32enc.c ├── b32enc.h ├── b32enc_usage.c ├── b64dec.c ├── b64dec.h ├── b64dec_usage.c ├── b64enc.c ├── b64enc.h ├── b64enc_usage.c ├── base32.c ├── base32.h ├── base64.c ├── base64.h ├── checksum.c ├── checksum.h ├── checksum_usage.c ├── common.h ├── config.in ├── crc32.c ├── crc32.h ├── crypto_nettle.c ├── crypto_nettle.h ├── crypto_ossl.c ├── crypto_ossl.h ├── deccb.c ├── deccb.h ├── deccb_usage.c ├── decexp.c ├── decexp.h ├── decexp_usage.c ├── decfile.c ├── decfile.h ├── decfile_usage.c ├── decoder.c ├── decoder.h ├── decoder_usage.c ├── decompose.c ├── decompose.h ├── decompose_usage.c ├── decsngl.c ├── decsngl.h ├── decsngl_usage.c ├── devpw.c ├── devpw.h ├── devpw_usage.c ├── encryption.c ├── encryption.h ├── environ.c ├── environ.h ├── errors.c ├── errors.h ├── exportfile.c ├── exportfile.h ├── functions.c ├── functions.h ├── help.c ├── help.h ├── hex.c ├── hex.h ├── hexdec.c ├── hexdec.h ├── hexdec_usage.c ├── hexenc.c ├── hexenc.h ├── hexenc_usage.c ├── license.c ├── license.h ├── memory.c ├── memory.h ├── nettle ├── Makefile └── download.sh ├── options.c ├── options.h ├── output.c ├── output.h ├── pkpwd.c ├── pkpwd.h ├── pkpwd_usage.c ├── pwfrdev.c ├── pwfrdev.h ├── pwfrdev_usage.c ├── userpw.c ├── userpw.h └── userpw_usage.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf 3 | 4 | # GPG public key uses CRLF 5 | PeterPawn.asc text eol=crlf 6 | 7 | # Custom for Visual Studio 8 | *.cs diff=csharp 9 | 10 | # Standard to msysgit 11 | *.doc diff=astextplain 12 | *.DOC diff=astextplain 13 | *.docx diff=astextplain 14 | *.DOCX diff=astextplain 15 | *.dot diff=astextplain 16 | *.DOT diff=astextplain 17 | *.pdf diff=astextplain 18 | *.PDF diff=astextplain 19 | *.rtf diff=astextplain 20 | *.RTF diff=astextplain 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site/ 2 | decoder.code-workspace 3 | -------------------------------------------------------------------------------- /Config.in: -------------------------------------------------------------------------------- 1 | config FREETZ_PACKAGE_DECODER 2 | bool "decoder 0.4" 3 | select FREETZ_LIB_libcrypto if ! FREETZ_PACKAGE_DECODER_STATIC 4 | default y 5 | help 6 | decrypt AVM cipher text - see https://github.com/PeterPawn/decoder 7 | 8 | It's a multi-call binary and you have to select the functions to install. 9 | 10 | config FREETZ_PACKAGE_DECODER_DYNAMIC 11 | depends on FREETZ_PACKAGE_DECODER 12 | bool "build dynamically linked binary" 13 | default n 14 | help 15 | Build the utility as a binary, which uses DSO's for smaller files. 16 | 17 | config FREETZ_PACKAGE_DECODER_LIBCRYPTO 18 | depends on FREETZ_PACKAGE_DECODER 19 | bool "use OpenSSL's libcrypto instead of an own libnettle version" 20 | default n 21 | help 22 | This is the smallest binary, but with the most dependencies on other libraries. 23 | 24 | menu "symlinks to create for 'decoder'" 25 | depends on FREETZ_PACKAGE_DECODER 26 | 27 | config FREETZ_PACKAGE_DECODER_DECODE_SECRETS 28 | depends on FREETZ_PACKAGE_DECODER 29 | bool "decode_secrets - decrypt cipher-text values" 30 | default y 31 | help 32 | This is a filter and copies all data from STDIN to STDOUT while decryptable 33 | cipher-text occurrences are replaced with their clear-text values. 34 | 35 | config FREETZ_PACKAGE_DECODER_DECODE_EXPORT 36 | depends on FREETZ_PACKAGE_DECODER 37 | bool "decode_export - decrypt settings export files" 38 | default n 39 | help 40 | This is a filter and copies all data from STDIN to STDOUT while decryptable 41 | cipher-text occurrences are replaced with their clear-text values. 42 | It's a replacement for 'decode_secrets' with automatic handling of the special 43 | encryption for the export password. 44 | 45 | config FREETZ_PACKAGE_DECODER_DECODE_CRYPTEDBINFILE 46 | depends on FREETZ_PACKAGE_DECODER 47 | bool "decode_cryptedbinfile - decrypt data portion of encrypted file sections within an export file" 48 | default n 49 | help 50 | This is a filter and decrypts the content (hexadecimal or - starting with FRITZ!OS 07.19 - 51 | Base64 encoded strings) from an encrypted entry (CRYPTEDBINFILE or CRYPTEDB64FILE) in an 52 | exported settings file. 53 | 54 | config FREETZ_PACKAGE_DECODER_DECODE_SECRET 55 | depends on FREETZ_PACKAGE_DECODER 56 | bool "decode_secret - decrypt a single value" 57 | default n 58 | help 59 | This function expects the encrypted data and the key as command line arguments. 60 | 61 | config FREETZ_PACKAGE_DECODER_SPLIT_EXPORT 62 | depends on FREETZ_PACKAGE_DECODER 63 | bool "split_export - split a complete FRITZ!OS settings export into the contained settings files" 64 | default n 65 | 66 | config FREETZ_PACKAGE_DECODER_USER_PASSWORD 67 | depends on FREETZ_PACKAGE_DECODER 68 | bool "user_password - create a decryption key from a specified password" 69 | default n 70 | 71 | config FREETZ_PACKAGE_DECODER_DEVICE_PASSWORD 72 | depends on FREETZ_PACKAGE_DECODER 73 | bool "device_password - create a decryption key from specified device properties" 74 | default n 75 | 76 | config FREETZ_PACKAGE_DECODER_PASSWORD_FROM_DEVICE 77 | depends on FREETZ_PACKAGE_DECODER 78 | bool "password_from_device - create a decryption key from device properties" 79 | default n 80 | 81 | config FREETZ_PACKAGE_DECODER_DECODE_PASSWORDS 82 | depends on FREETZ_PACKAGE_DECODER 83 | bool "decode_passwords - this is an older synonym for 'decode_secrets'" 84 | default n 85 | 86 | config FREETZ_PACKAGE_DECODER_HEXUTIL 87 | depends on FREETZ_PACKAGE_DECODER 88 | bool "hexdec/hexenc - convert from hexadecimal to binary and vice versa" 89 | default n 90 | 91 | config FREETZ_PACKAGE_DECODER_B64UTIL 92 | depends on FREETZ_PACKAGE_DECODER 93 | bool "b64dec/b64enc - convert from Base64 to binary and vice versa" 94 | default n 95 | 96 | config FREETZ_PACKAGE_DECODER_B32UTIL 97 | depends on FREETZ_PACKAGE_DECODER 98 | bool "b32dec/b32enc - convert from Base32 to binary and vice versa" 99 | default n 100 | 101 | endmenu 102 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | # 3 | # project 4 | # 5 | BASENAME:=decoder 6 | # 7 | # binary directory 8 | # 9 | SRC_DIR=src 10 | # 11 | # shell scripts directory 12 | # 13 | SCRIPTS_DIR=scripts 14 | # 15 | # targets to make 16 | # 17 | .PHONY: all clean install uninstall install-scripts uninstall-scripts 18 | # 19 | # targets 20 | # 21 | all: decoder 22 | 23 | decoder: 24 | $(MAKE) -C $(SRC_DIR) 25 | 26 | install: 27 | $(MAKE) -C $(SRC_DIR) install 28 | 29 | uninstall: 30 | $(MAKE) -C $(SRC_DIR) uninstall 31 | 32 | install-scripts: 33 | $(MAKE) -C $(SCRIPTS_DIR) install 34 | 35 | uninstall-scripts: 36 | $(MAKE) -C $(SCRIPTS_DIR) uninstall 37 | 38 | clean: 39 | $(MAKE) -C $(SRC_DIR) clean 40 | -------------------------------------------------------------------------------- /bin/.gitattributes: -------------------------------------------------------------------------------- 1 | # this folder and its subfolders contain only binary data 2 | *.md text eol=lf 3 | decoder* binary 4 | -------------------------------------------------------------------------------- /bin/README.md: -------------------------------------------------------------------------------- 1 | ### 'ready to use' files 2 | This folder contains some pre-built binaries, all of them are linked statically and it should be possible to execute them without any further precautions, after you've copied the file for your platform to the target system and made it executable (with ```chmod```). If you want to use a file on a regular base, you should create symbolic links for the wanted applets. 3 | 4 | Please don't forget to check the detached GnuPG signature, provided together with each binary file. You can find my public key (```KeyID 0x30311D96```) on ```keys.gnupg.net``` or as file ```PeterPawn.asc``` in the root folder of this project. 5 | 6 | The files provided and their target platforms are: 7 | 8 | * decoder.armv7l 9 | - built with ```libnettle``` (3.6) and ```uClibc-ng``` (1.0.14) using the ```Freetz``` toolchain (from my YourFreetz fork) for IPQ40x8/9 devices 10 | * decoder.mips 11 | - built for ```big endian``` machines with ```libnettle``` (3.6) and ```uClibc-ng``` (1.0.14) using the ```Freetz``` toolchain (from my YourFreetz fork) 12 | - should be usable on all FRITZ!Box models with VR9 and GRX5 chipset, works on Vx180 (7390), too 13 | * decoder.i686 14 | - built with ```libnettle``` (3.6) and ```uClibc-ng``` (1.0.14), targeting Intel 80386 compatible systems (Puma's ATOM and other x86 platforms) 15 | * decoder.x86_64 16 | - built with ```libnettle``` (3.6) and ```glibc```, targeting x64 compatible systems 17 | - should be usable from WSL (Windows Subsystem for Linux) on Windows 10 18 | - somewhat larger due to the usage of ```glibc``` 19 | -------------------------------------------------------------------------------- /bin/decoder.armv7l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.armv7l -------------------------------------------------------------------------------- /bin/decoder.armv7l.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.armv7l.sig -------------------------------------------------------------------------------- /bin/decoder.i686: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.i686 -------------------------------------------------------------------------------- /bin/decoder.i686.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.i686.sig -------------------------------------------------------------------------------- /bin/decoder.mips: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.mips -------------------------------------------------------------------------------- /bin/decoder.mips.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.mips.sig -------------------------------------------------------------------------------- /bin/decoder.x86_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.x86_64 -------------------------------------------------------------------------------- /bin/decoder.x86_64.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/decoder/d6fdd1a58ae891aa7a7b9aef190ce51de10c2251/bin/decoder.x86_64.sig -------------------------------------------------------------------------------- /decoder.mk: -------------------------------------------------------------------------------- 1 | $(call PKG_INIT_BIN, v0.4) 2 | 3 | $(PKG)_BINARY:=$($(PKG)_DIR)/decoder 4 | $(PKG)_TARGET_BINARY:=$($(PKG)_DEST_DIR)/bin/decoder 5 | 6 | $(PKG)_DEPENDS_ON += $(if $(FREETZ_PACKAGE_DECODER_LIBCRYPTO),openssl,nettle) 7 | 8 | $(PKG_LOCALSOURCE_PACKAGE) 9 | $(PKG_CONFIGURED_NOP) 10 | 11 | $($(PKG)_BINARY): $($(PKG)_DIR)/.configured 12 | $(SUBMAKE) -C $(DECODER_DIR) \ 13 | CC="$(TARGET_CC)" \ 14 | CFLAGS="$(TARGET_CFLAGS)" \ 15 | OPT="" \ 16 | OPENSSL=$(if $(FREETZ_PACKAGE_DECODER_LIBCRYPTO),y,n) \ 17 | STATIC=$(if $(FREETZ_PACKAGE_DECODER_DYNAMIC),n,y) \ 18 | NETTLE_HOST=$(TARGET_GNU_TRIPLET) \ 19 | NETTLE_TARGET=$(REAL_GNU_TARGET_NAME) \ 20 | NETTLE_BUILD=$(GNU_HOST_NAME) 21 | 22 | $($(PKG)_TARGET_BINARY): $($(PKG)_BINARY) 23 | $(INSTALL_BINARY_STRIP) 24 | 25 | $(pkg): 26 | 27 | $(pkg)-precompiled: $($(PKG)_TARGET_BINARY) 28 | 29 | $(pkg)-clean: 30 | -$(SUBMAKE) -C $(DECODER_DIR) clean 31 | 32 | $(pkg)-uninstall: 33 | $(SUBMAKE) -C $(DECODER_DIR) \ 34 | bindir="$(dir $@)" \ 35 | uninstall 36 | 37 | $(PKG_FINISH) 38 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /extras/cryptedbin.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # create an export file with an encrypted binary file 5 | # 6 | # MUST BE EXECUTED ON A FRITZ!OS DEVICE 7 | # 8 | # COMMENT: It looks like AVM isn't using the encryption anymore for "dvb.cfg", 9 | # starting with FRITZ!OS version 07.19. At least the file is exported 10 | # on my 7490 device (with 113.07.19-73513) without encryption, as a 11 | # normal B64FILE entry. 12 | # UPDATE: Even the labor version for 6490 (141.07.19-75251) does not use an 13 | # encryption anymore for 'dvb.cfg' file. The whole 'CRYPTEDB64FILE' 14 | # support is based on assumptions from the earlier 'CRYPTEDBINFILE' 15 | # implementation. 16 | # 17 | # remove the character device for an existing dvb.cfg file 18 | # 19 | rm /var/flash/dvb.cfg 2>/dev/null 20 | # 21 | # create our own file 22 | # 23 | cat >/var/flash/dvb.cfg <<'EOT' 24 | /* 25 | * /var/flash/dvb.cfg 26 | * Sun May 14 20:57:35 2017 27 | */ 28 | 29 | meta { encoding = "utf-8"; } 30 | 31 | version_dvb { 32 | revision = "$Revision: 1.0 $"; 33 | creatversion = "1.00.00"; 34 | } 35 | 36 | 37 | dvbcfg { 38 | nit_pid = 16; 39 | network_id = 61444; 40 | network_name = "Kabel Deutschland"; 41 | bouquets = 32; 42 | tv_services = 101; 43 | radio_services = 67; 44 | other_services = 0; 45 | channels { 46 | sid = 53019; 47 | tsid = 10008; 48 | frequency = 442000000; 49 | lcn_nordig = 0; 50 | lcn_eacem = 0; 51 | flags = 32; 52 | url = 239.2.1.1; 53 | provider = ""; 54 | name = "53019"; 55 | type = 0; 56 | ca_mode = 0; 57 | pid_pmt = 220; 58 | pid_pcr = 0; 59 | pid_cnt = 0; 60 | } 61 | } 62 | 63 | 64 | // EOF 65 | EOT 66 | # 67 | # declare TV functions active 68 | # 69 | export CONFIG_LINEARTV=y 70 | # 71 | # export the data with or without password 72 | # 73 | # ATTENTION: 74 | # 75 | # It looks like AVM disabled (accident or not, that's the question) the ability 76 | # to export data without a password, since 2FA was added to the firmware. 77 | # Exporting a file without password is not functioning on any of my 06.83 devices. 78 | # 79 | # We strip off all lines around the encrypted content. 80 | # 81 | tr069fwupdate configexport $1 | sed -n -e "/\*\*\*\* CRYPTEDB\(IN\|64\)FILE/,/\*\*\*\* END OF FILE/p" | sed -e "1d;\$d" 82 | # 83 | # data should be visible on STDOUT now 84 | # 85 | -------------------------------------------------------------------------------- /scripts/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | # 3 | # targets to make 4 | # 5 | .PHONY: install $(call LINK_NAMES,$(LINKS)) 6 | # 7 | # script files to copy 8 | # 9 | SCRIPTS += crypto 10 | SCRIPTS += decode_cryptedbinfile 11 | SCRIPTS += decode_export 12 | SCRIPTS += decode_secret 13 | SCRIPTS += decode_secrets 14 | SCRIPTS += device_password 15 | SCRIPTS += password_from_device 16 | SCRIPTS += privatekeypassword 17 | SCRIPTS += user_password 18 | # 19 | # symlinks to create 20 | # 21 | LINKS += (decode_passwords, decode_secrets) 22 | LINKS += (test123 test456, test2) 23 | # 24 | # ANSI control sequences for colored messages 25 | # 26 | MSGGREEN:=$(shell printf "\033[32m") 27 | MSGRED:=$(shell printf "\033[31m") 28 | MSGRESET:=$(shell printf "\033[0m") 29 | MSGBOLD:=$(shell printf "\033[1m") 30 | define MSG_NEWLINE 31 | $(info $(shell printf "\n\n")) 32 | endef 33 | # 34 | # check TARGET variable 35 | # 36 | ifeq ($(TARGET),) 37 | $(error $(MSGRED)$(MSGBOLD)Missing TARGET definition.$(MSGRESET)) 38 | endif 39 | # 40 | # use shell to extract from LINKS definition 41 | # 42 | OPAR:=( 43 | CPAR:=) 44 | define LINK_NAMES 45 | $(shell printf "%s" "$(1)" | sed -n -e "s|$(OPAR)\$(OPAR)[^,]*\$(CPAR),[^$(CPAR)]*$(CPAR)|\1|gp") 46 | endef 47 | define LINK_ENTRIES 48 | $(shell printf "%s" "$(1)" | sed -n -e "s|$(OPAR)|\"$(OPAR)|g;s|$(CPAR)|$(CPAR)\"|gp") 49 | endef 50 | # 51 | # show install destination 52 | # 53 | $(info $(MSGGREEN)$(MSGBOLD)install directory:$(MSGRESET) $(MSGBOLD)$(TARGET)$(MSGRESET)) 54 | $(call MSG_NEWLINE) 55 | $(info ======================================) 56 | # 57 | # install to TARGET directory (which has to exist already) 58 | # 59 | # do not use 'install' utility here, because it's missing on FRITZ!OS devices as well (where an existing 60 | # 'make' would be a miracle already) 61 | # 62 | install-scripts: $(SCRIPTS) 63 | @test -d $(TARGET) || (printf "Target directory '$(TARGET)' does not exist.\n" 1>&2 && false) 64 | cp -av $^ $(TARGET) 65 | 66 | install-links: 67 | @for links in $(call LINK_ENTRIES,$(LINKS)); do \ 68 | target="$$(printf "%s" "$$links" | sed -n -e "s|.*,[ ]*\(.[^)]*\))|\1|gp")"; \ 69 | link="$$(printf "%s" "$$links" | sed -n -e "s|(\([^,]*\),.*|\1|gp")"; \ 70 | for l in $$link; do \ 71 | printf "Linking '$(TARGET)/$$l' to '$(TARGET)/$$target' ...\n" 1>&2; \ 72 | opwd=$$PWD; \ 73 | cd $(TARGET); \ 74 | ln -s $$target $$l; \ 75 | cd $$opwd; \ 76 | done; \ 77 | done 78 | 79 | install: install-scripts install-links 80 | # 81 | # uninstall 82 | # 83 | uninstall: 84 | @for name in $(call LINK_NAMES,$(LINKS)) $(SCRIPTS); do \ 85 | printf "Removing $(TARGET)/$$name\n" 1>&2; \ 86 | rm $(TARGET)/$$name 2>/dev/null; \ 87 | done; \ 88 | true 89 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.exe 3 | -------------------------------------------------------------------------------- /src/b32dec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define B32DEC_C 23 | 24 | #include "common.h" 25 | #include "b32dec_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "b32dec_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __b32dec_command = { .names = &commandNames, .ep = &b32dec_entry, .usage = &b32dec_usage, .short_desc = &b32dec_shortdesc }; 37 | EXPORTED commandEntry_t * b32dec_command = &__b32dec_command; 38 | 39 | // 'b32dec' function - decode Base32 encoded data from STDIN to STDOUT 40 | 41 | int b32dec_output(char * base32, bool hexOutput, size_t * charsOnLine) 42 | { 43 | char binary[5]; 44 | size_t binarySize = base32ToBinary(base32, (size_t) -1, binary, sizeof(binary)); 45 | char hex[11]; 46 | char * out; 47 | size_t outSize; 48 | 49 | if (isAnyError()) /* usually invalid characters */ 50 | { 51 | if (isError(INV_B32_DATA)) 52 | { 53 | errorMessage(errorInvalidValue); 54 | } 55 | else if (isError(INV_B32_SIZE)) 56 | { 57 | errorMessage(errorInvalidDataSize); 58 | } 59 | else 60 | { 61 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 62 | } 63 | return EXIT_FAILURE; 64 | } 65 | if (hexOutput) 66 | { 67 | outSize = binaryToHexadecimal(binary, binarySize, hex, sizeof(hex)); 68 | out = hex; 69 | out = wrapOutput(stdout, charsOnLine, &outSize, out); 70 | } 71 | else 72 | { 73 | outSize = binarySize; 74 | out = binary; 75 | } 76 | if (fwrite(out, outSize, 1, stdout) != 1) 77 | { 78 | setError(WRITE_FAILED); 79 | errorMessage(errorWriteFailed); 80 | return EXIT_FAILURE; 81 | } 82 | *charsOnLine += outSize; 83 | 84 | return EXIT_SUCCESS; 85 | } 86 | 87 | int b32dec_entry(int argc, char** argv, int argo, commandEntry_t * entry) 88 | { 89 | char buffer[81]; 90 | char * input; 91 | char base32[9]; 92 | int convUsed = 0; 93 | bool hexOutput = false; 94 | size_t charsOnLine = 0; 95 | bool begin = true; 96 | 97 | if (argc > argo + 1) 98 | { 99 | int opt; 100 | int optIndex = 0; 101 | 102 | static struct option options_long[] = { 103 | { "hex-output", no_argument, NULL, 'x' }, 104 | width_options_long, 105 | verbosity_options_long, 106 | options_long_end, 107 | }; 108 | char * options_short = ":" "x" width_options_short verbosity_options_short; 109 | 110 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 111 | { 112 | switch (opt) 113 | { 114 | case 'x': 115 | hexOutput = true; 116 | entry->finalNewlineOnTTY = true; 117 | break; 118 | 119 | check_width_options_short(); 120 | check_verbosity_options_short(); 121 | help_option(); 122 | getopt_invalid_option(); 123 | invalid_option(opt); 124 | } 125 | } 126 | if (optind < argc) 127 | warnAboutExtraArguments(argv, optind + 1); 128 | } 129 | 130 | if (getLineWrap() && !hexOutput) 131 | { 132 | warningMessage(verboseWrapLinesIgnored); 133 | failOnStrict(); 134 | } 135 | 136 | if (isatty(0)) 137 | { 138 | errorMessage(errorNoReadFromTTY); 139 | return EXIT_FAILURE; 140 | } 141 | 142 | if (isAnyError()) 143 | return EXIT_FAILURE; 144 | 145 | resetError(); 146 | 147 | while ((input = fgets(buffer, sizeof(buffer), stdin)) != NULL) 148 | { 149 | input--; 150 | while (*(++input)) 151 | { 152 | if (isspace(*input) || (begin && *input == '$')) 153 | continue; 154 | begin = false; 155 | base32[convUsed++] = *input; 156 | if (convUsed == 8) 157 | { 158 | int result; 159 | 160 | base32[convUsed] = 0; 161 | if ((result = b32dec_output(base32, hexOutput, &charsOnLine))) 162 | return result; 163 | convUsed = 0; 164 | } 165 | } 166 | } 167 | 168 | if (convUsed > 0) /* remaining data exist */ 169 | { 170 | base32[convUsed] = 0; 171 | return b32dec_output(base32, hexOutput, &charsOnLine); 172 | } 173 | 174 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 175 | } 176 | 177 | #pragma GCC diagnostic pop 178 | -------------------------------------------------------------------------------- /src/b32dec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef B32DEC_H 23 | 24 | #define B32DEC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void b32dec_usage(const bool help, const bool version); 31 | int b32dec_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef B32DEC_C 34 | 35 | extern commandEntry_t * b32dec_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/b32dec_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void b32dec_usage(const bool help, const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program takes Base32 encoded data from STDIN and decodes it to binary.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 48 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) for textual output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 49 | addOptionsEntryVerbose(); 50 | addOptionsEntryQuiet(); 51 | addOptionsEntryStrict(); 52 | addOptionsEntryHelp(); 53 | addOptionsEntryVersion(); 54 | showOptionsEnd(out); 55 | 56 | fprintf(out, 57 | "\nThe decoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 58 | "aborted.\n" 59 | ); 60 | 61 | fprintf(out, 62 | "\nYou may specify the '--hex-output' (or '-x') option to output data with hexadecimal encoding. If you\n" 63 | "use this option, you can force lines with limited width using the '--wrap-lines' (or '-w') option.\n" 64 | "Optionally you can set your wanted line width too.\n" 65 | ); 66 | 67 | showUsageFinalize(out, help, version); 68 | } 69 | 70 | char * b32dec_shortdesc(void) 71 | { 72 | return "decode Base32 encoded data"; 73 | } 74 | -------------------------------------------------------------------------------- /src/b32enc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define B32ENC_C 23 | 24 | #include "common.h" 25 | #include "b32enc_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "b32enc_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __b32enc_command = { .names = &commandNames, .ep = &b32enc_entry, .usage = &b32enc_usage, .short_desc = &b32enc_shortdesc, .finalNewlineOnTTY = true }; 37 | EXPORTED commandEntry_t * b32enc_command = &__b32enc_command; 38 | 39 | // 'b32enc' function - encode binary data from STDIN to Base32 encoded on STDOUT 40 | 41 | int b32enc_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | bool hexInput = false; 44 | bool padInput = false; 45 | char buffer[20]; 46 | size_t read = 0; 47 | size_t charsOnLine = 0; 48 | 49 | if (argc > argo + 1) 50 | { 51 | int opt; 52 | int optIndex = 0; 53 | 54 | static struct option options_long[] = { 55 | { "hex-input", no_argument, NULL, 'x' }, 56 | { "pad-input", no_argument, NULL, 'p' }, 57 | width_options_long, 58 | verbosity_options_long, 59 | options_long_end, 60 | }; 61 | char * options_short = ":" "xp" width_options_short verbosity_options_short; 62 | 63 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 64 | { 65 | switch (opt) 66 | { 67 | case 'x': 68 | hexInput = true; 69 | break; 70 | 71 | case 'p': 72 | padInput = true; 73 | break; 74 | 75 | check_width_options_short(); 76 | check_verbosity_options_short(); 77 | help_option(); 78 | getopt_invalid_option(); 79 | invalid_option(opt); 80 | } 81 | } 82 | if (optind < argc) 83 | warnAboutExtraArguments(argv, optind + 1); 84 | } 85 | 86 | if (isatty(0)) 87 | { 88 | errorMessage(errorNoReadFromTTY); 89 | return EXIT_FAILURE; 90 | } 91 | 92 | if (isAnyError()) 93 | return EXIT_FAILURE; 94 | 95 | resetError(); 96 | 97 | while ((read = fread(buffer, 1, sizeof(buffer), stdin)) > 0) 98 | { 99 | if (hexInput) 100 | { 101 | char withoutSpaces[sizeof(buffer)]; 102 | size_t used = 0; 103 | char * in; 104 | char * out; 105 | int i; 106 | size_t more = read; 107 | 108 | in = buffer; 109 | out = withoutSpaces; 110 | while (more > 0) 111 | { 112 | for (i = more; i > 0; i--, in++) 113 | { 114 | if (isspace(*(in))) 115 | continue; 116 | *(out++) = *in; 117 | used++; 118 | } 119 | if (used == sizeof(withoutSpaces)) 120 | break; 121 | more = fread(buffer, 1, sizeof(withoutSpaces) - used, stdin); 122 | if (more == 0) 123 | break; 124 | in = buffer; 125 | } 126 | read = hexadecimalToBinary(withoutSpaces, used, buffer, sizeof(buffer)); 127 | if (read == 0) 128 | break; 129 | } 130 | if ((read % 5)) 131 | { 132 | if (padInput) 133 | { 134 | int r = 5 - (read % 5); 135 | char * pad = &buffer[read]; 136 | 137 | for (int i = 0; i < r; i++) 138 | { 139 | *pad++ = 0; 140 | read++; 141 | } 142 | } 143 | else 144 | { 145 | setError(INV_B32_ENC_SIZE); 146 | read = 0; 147 | break; 148 | } 149 | } 150 | 151 | char base32[(sizeof(buffer) / 5 * 8) + 1]; 152 | size_t base32Size = binaryToBase32(buffer, read, base32, sizeof(base32) - 1); 153 | 154 | if (base32Size > 0) 155 | { 156 | char * out = base32; 157 | 158 | out = wrapOutput(stdout, &charsOnLine, &base32Size, base32); 159 | if (fwrite(out, base32Size, 1, stdout) != 1) 160 | { 161 | setError(WRITE_FAILED); 162 | errorMessage(errorWriteFailed); 163 | return EXIT_FAILURE; 164 | } 165 | charsOnLine += base32Size; 166 | } 167 | } 168 | 169 | if (isAnyError()) 170 | { 171 | if (isError(INV_HEX_DATA)) 172 | { 173 | errorMessage(errorInvalidHexValue); 174 | } 175 | else if (isError(INV_HEX_SIZE)) 176 | { 177 | errorMessage(errorInvalidHexSize); 178 | } 179 | else if (isError(INV_B32_ENC_SIZE)) 180 | { 181 | errorMessage(errorInvalidDataSize); 182 | } 183 | else 184 | { 185 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 186 | } 187 | } 188 | 189 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 190 | } 191 | 192 | #pragma GCC diagnostic pop 193 | -------------------------------------------------------------------------------- /src/b32enc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef B32ENC_H 23 | 24 | #define B32ENC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void b32enc_usage(const bool help, const bool version); 31 | int b32enc_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef B32ENC_C 34 | 35 | extern commandEntry_t * b32enc_command; 36 | 37 | #endif 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/b32enc_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void b32enc_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program encodes data from STDIN into a Base32 representation.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-x, --hex-input", "input data is a hexadecimal string", 0); 48 | addOptionsEntry("-p, --pad-input", "input data size has to be a multiple of 5, if you do not specify this option", 0); 49 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) on output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 50 | addOptionsEntryVerbose(); 51 | addOptionsEntryQuiet(); 52 | addOptionsEntryStrict(); 53 | addOptionsEntryHelp(); 54 | addOptionsEntryVersion(); 55 | showOptionsEnd(out); 56 | 57 | fprintf(out, 58 | "\nThe encoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 59 | "aborted.\n" 60 | ); 61 | 62 | fprintf(out, 63 | "\nInput data may be encoded as hexadecimal string. In this case, any white-space between the digits will\n" 64 | "be ignored.\n" 65 | ); 66 | 67 | fprintf(out, 68 | "\nYou can force output of lines with limited width using the '--wrap-lines' (or '-w') option. Optionally\n" 69 | "you can set your wanted line width too.\n" 70 | ); 71 | 72 | showUsageFinalize(out, help, version); 73 | } 74 | 75 | char * b32enc_shortdesc(void) 76 | { 77 | return "encode data to Base32 representation"; 78 | } 79 | -------------------------------------------------------------------------------- /src/b64dec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define B64DEC_C 23 | 24 | #include "common.h" 25 | #include "b64dec_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "b64dec_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __b64dec_command = { .names = &commandNames, .ep = &b64dec_entry, .short_desc = &b64dec_shortdesc, .usage = &b64dec_usage }; 37 | EXPORTED commandEntry_t * b64dec_command = &__b64dec_command; 38 | 39 | // 'b64dec' function - decode Base64 encoded data from STDIN to STDOUT 40 | 41 | int b64dec_output(char * base64, bool hexOutput, bool pad, size_t * charsOnLine) 42 | { 43 | char binary[3]; 44 | size_t binarySize = base64ToBinary(base64, (size_t) -1, binary, sizeof(binary), pad, false); 45 | char hex[6]; 46 | char * out; 47 | size_t outSize; 48 | 49 | if (isAnyError()) /* usually invalid characters */ 50 | { 51 | if (isError(INV_B64_DATA)) 52 | { 53 | errorMessage(errorInvalidValue); 54 | } 55 | else if (isError(INV_B64_SIZE)) 56 | { 57 | errorMessage(errorInvalidDataSize); 58 | } 59 | else 60 | { 61 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 62 | } 63 | return EXIT_FAILURE; 64 | } 65 | if (hexOutput) 66 | { 67 | outSize = binaryToHexadecimal(binary, binarySize, hex, sizeof(hex)); 68 | out = hex; 69 | out = wrapOutput(stdout, charsOnLine, &outSize, out); 70 | } 71 | else 72 | { 73 | outSize = binarySize; 74 | out = binary; 75 | } 76 | if (fwrite(out, outSize, 1, stdout) != 1) 77 | { 78 | setError(WRITE_FAILED); 79 | errorMessage(errorWriteFailed); 80 | return EXIT_FAILURE; 81 | } 82 | *charsOnLine += outSize; 83 | 84 | return EXIT_SUCCESS; 85 | } 86 | 87 | int b64dec_entry(int argc, char** argv, int argo, commandEntry_t * entry) 88 | { 89 | char buffer[80]; 90 | char * input; 91 | char base64[5]; 92 | int convUsed = 0; 93 | bool hexOutput = false; 94 | bool padOutput = false; 95 | size_t charsOnLine = 0; 96 | 97 | if (argc > argo + 1) 98 | { 99 | int opt; 100 | int optIndex = 0; 101 | 102 | static struct option options_long[] = { 103 | { "hex-output", no_argument, NULL, 'x' }, 104 | { "pad-output", no_argument, NULL, 'p' }, 105 | width_options_long, 106 | verbosity_options_long, 107 | options_long_end, 108 | }; 109 | char * options_short = ":" "xp" width_options_short verbosity_options_short; 110 | 111 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 112 | { 113 | switch (opt) 114 | { 115 | case 'x': 116 | hexOutput = true; 117 | entry->finalNewlineOnTTY = true; 118 | break; 119 | 120 | case 'p': 121 | padOutput = true; 122 | break; 123 | 124 | check_width_options_short(); 125 | check_verbosity_options_short(); 126 | help_option(); 127 | getopt_invalid_option(); 128 | invalid_option(opt); 129 | } 130 | } 131 | } 132 | 133 | if (getLineWrap() && !hexOutput) 134 | { 135 | warningMessage(verboseWrapLinesIgnored); 136 | failOnStrict(); 137 | } 138 | 139 | if (isatty(0)) 140 | { 141 | errorMessage(errorNoReadFromTTY); 142 | return EXIT_FAILURE; 143 | } 144 | 145 | if (isAnyError()) 146 | return EXIT_FAILURE; 147 | 148 | resetError(); 149 | 150 | while ((input = fgets(buffer, sizeof(buffer), stdin)) != NULL) 151 | { 152 | input--; 153 | while (*(++input)) 154 | { 155 | if (isspace(*input)) 156 | continue; 157 | base64[convUsed++] = *input; 158 | if (convUsed == 4) 159 | { 160 | int result; 161 | 162 | base64[convUsed] = 0; 163 | if ((result = b64dec_output(base64, hexOutput, padOutput, &charsOnLine))) 164 | return result; 165 | convUsed = 0; 166 | } 167 | } 168 | } 169 | 170 | if (convUsed > 0) /* remaining data exist */ 171 | { 172 | base64[convUsed] = 0; 173 | return b64dec_output(base64, hexOutput, padOutput, &charsOnLine); 174 | } 175 | 176 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 177 | } 178 | 179 | #pragma GCC diagnostic pop 180 | -------------------------------------------------------------------------------- /src/b64dec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef B64DEC_H 23 | 24 | #define B64DEC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void b64dec_usage(const bool help, const bool version); 31 | int b64dec_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef B64DEC_C 34 | 35 | extern commandEntry_t * b64dec_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/b64dec_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void b64dec_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program takes Base64 encoded data from STDIN and decodes it to binary.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-p, --pad-output", "pad output data (with binary zeros) to a size, which is a multiple of 3, if input data size isn't a multiple of 4", 0); 48 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 49 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) for textual output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 50 | addOptionsEntryVerbose(); 51 | addOptionsEntryQuiet(); 52 | addOptionsEntryStrict(); 53 | addOptionsEntryHelp(); 54 | addOptionsEntryVersion(); 55 | showOptionsEnd(out); 56 | 57 | fprintf(out, 58 | "\nThe decoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 59 | "aborted.\n" 60 | ); 61 | 62 | fprintf(out, 63 | "\nYou may specify the '--hex-output' (or '-x') option to output data with hexadecimal encoding. If you\n" 64 | "use this option, you can force lines with limited width using the '--wrap-lines' (or '-w') option.\n" 65 | "Optionally you can set your wanted line width too.\n" 66 | ); 67 | 68 | showUsageFinalize(out, help, version); 69 | } 70 | 71 | char * b64dec_shortdesc(void) 72 | { 73 | return "decode Base64 encoded data"; 74 | } 75 | -------------------------------------------------------------------------------- /src/b64enc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define B64ENC_C 23 | 24 | #include "common.h" 25 | #include "b64enc_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "b64enc_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __b64enc_command = { .names = &commandNames, .ep = &b64enc_entry, .usage = &b64enc_usage, .short_desc = &b64enc_shortdesc, .finalNewlineOnTTY = true }; 37 | EXPORTED commandEntry_t * b64enc_command = &__b64enc_command; 38 | 39 | // 'b64enc' function - encode binary data from STDIN to Base64 encoded on STDOUT 40 | 41 | int b64enc_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | bool hexInput = false; 44 | bool padOutput = false; 45 | size_t charsOnLine = 0; 46 | char buffer[120]; 47 | size_t read = 0; 48 | 49 | if (argc > argo + 1) 50 | { 51 | int opt; 52 | int optIndex = 0; 53 | 54 | static struct option options_long[] = { 55 | { "hex-input", no_argument, NULL, 'x' }, 56 | { "pad-output", no_argument, NULL, 'p' }, 57 | width_options_long, 58 | verbosity_options_long, 59 | options_long_end, 60 | }; 61 | char * options_short = ":" "xp" width_options_short verbosity_options_short; 62 | 63 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 64 | { 65 | switch (opt) 66 | { 67 | case 'x': 68 | hexInput = true; 69 | break; 70 | 71 | case 'p': 72 | padOutput = true; 73 | break; 74 | 75 | check_width_options_short(); 76 | check_verbosity_options_short(); 77 | help_option(); 78 | getopt_invalid_option(); 79 | invalid_option(opt); 80 | } 81 | } 82 | if (optind < argc) 83 | warnAboutExtraArguments(argv, optind + 1); 84 | } 85 | 86 | if (isatty(0)) 87 | { 88 | errorMessage(errorNoReadFromTTY); 89 | return EXIT_FAILURE; 90 | } 91 | 92 | if (isAnyError()) 93 | return EXIT_FAILURE; 94 | 95 | resetError(); 96 | 97 | while ((read = fread(buffer, 1, sizeof(buffer), stdin)) > 0) 98 | { 99 | if (hexInput) 100 | { 101 | char withoutSpaces[sizeof(buffer)]; 102 | size_t used = 0; 103 | char * in; 104 | char * out; 105 | int i; 106 | size_t more = read; 107 | 108 | in = buffer; 109 | out = withoutSpaces; 110 | while (more > 0) 111 | { 112 | for (i = more; i > 0; i--, in++) 113 | { 114 | if (isspace(*(in))) 115 | continue; 116 | *(out++) = *in; 117 | used++; 118 | } 119 | if (used == sizeof(withoutSpaces)) 120 | break; 121 | more = fread(buffer, 1, sizeof(withoutSpaces) - used, stdin); 122 | if (more == 0) 123 | break; 124 | in = buffer; 125 | } 126 | read = hexadecimalToBinary(withoutSpaces, used, buffer, sizeof(buffer)); 127 | if (read == 0) 128 | break; 129 | } 130 | 131 | char base64[(sizeof(buffer) * 4 / 3) + 1]; /* one more byte for optional end of string */ 132 | size_t base64Size = binaryToBase64(buffer, read, base64, sizeof(base64) - 1, padOutput); 133 | 134 | if (base64Size == 0) break; 135 | 136 | size_t toWrite = base64Size; 137 | char * out = base64; 138 | 139 | out = wrapOutput(stdout, &charsOnLine, &toWrite, out); 140 | if (isAnyError()) 141 | break; 142 | 143 | if ((toWrite > 0) && fwrite(out, toWrite, 1, stdout) != 1) 144 | { 145 | setError(WRITE_FAILED); 146 | break; 147 | } 148 | charsOnLine += toWrite; 149 | } 150 | if (!isAnyError()) 151 | wrapOutput(stdout, &charsOnLine, NULL, NULL); 152 | 153 | if (isAnyError()) 154 | { 155 | if (isError(WRITE_FAILED)) 156 | { 157 | errorMessage(errorWriteFailed); 158 | } 159 | else if (isError(INV_HEX_DATA)) 160 | { 161 | errorMessage(errorInvalidHexValue); 162 | } 163 | else if (isError(INV_HEX_SIZE)) 164 | { 165 | errorMessage(errorInvalidHexSize); 166 | } 167 | else if (isError(INV_B64_ENC_SIZE)) 168 | { 169 | errorMessage(errorInvalidDataSize); 170 | } 171 | else 172 | { 173 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 174 | } 175 | } 176 | 177 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 178 | } 179 | 180 | #pragma GCC diagnostic pop 181 | -------------------------------------------------------------------------------- /src/b64enc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef B64ENC_H 23 | 24 | #define B64ENC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void b64enc_usage(const bool help, const bool version); 31 | int b64enc_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef B64ENC_C 34 | 35 | extern commandEntry_t * b64enc_command; 36 | 37 | #endif 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/b64enc_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void b64enc_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program encodes data from STDIN into a Base64 representation.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-x, --hex-input", "input data is a hexadecimal string", 0); 48 | addOptionsEntry("-p, --pad-output", "output data will be padded with equal signs to a size, which is a multiple of 4", 0); 49 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) on output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 50 | addOptionsEntryVerbose(); 51 | addOptionsEntryQuiet(); 52 | addOptionsEntryStrict(); 53 | addOptionsEntryHelp(); 54 | addOptionsEntryVersion(); 55 | showOptionsEnd(out); 56 | 57 | fprintf(out, 58 | "\nThe encoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 59 | "aborted.\n" 60 | ); 61 | 62 | fprintf(out, 63 | "\nInput data may be encoded as hexadecimal string. In this case, any white-space between the digits will\n" 64 | "be ignored.\n" 65 | ); 66 | 67 | fprintf(out, 68 | "\nYou can force output of lines with limited width using the '--wrap-lines' (or '-w') option. Optionally\n" 69 | "you can set your wanted line width too.\n" 70 | ); 71 | 72 | showUsageFinalize(out, help, version); 73 | } 74 | 75 | char * b64enc_shortdesc(void) 76 | { 77 | return "encode data to Base64 representation"; 78 | } 79 | -------------------------------------------------------------------------------- /src/base32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define BASE32_C 23 | 24 | #include "base32.h" 25 | 26 | // Base32 encoding table 27 | 28 | static char * UNUSED base32Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; 29 | 30 | // Base32 conversion functions 31 | 32 | // convert a Base32 string to a binary buffer 33 | 34 | size_t base32ToBinary(char *base32, size_t base32Size, char *binary, size_t binarySize) 35 | { 36 | size_t offset = 0; 37 | size_t outOffset = 0; 38 | size_t b32Size = (base32Size == (size_t) -1 ? strlen(base32) : base32Size); 39 | 40 | if (b32Size % 8) 41 | returnError(INV_B32_SIZE, 0); 42 | if ((b32Size * 5 / 8) > binarySize) 43 | returnError(BUF_TOO_SMALL, (b32Size * 5 / 8)); 44 | while (offset < b32Size && outOffset < binarySize) 45 | { 46 | int bits = 0; 47 | int value = 0; 48 | 49 | for (int i = 0; i < 8; i++) 50 | { 51 | char c = *(base32 + offset + i); 52 | 53 | if (c >= 'A' && c <= 'Z') 54 | c = c - 'A'; 55 | else if (c >= '1' && c <= '6') 56 | c = c - '1' + 26; 57 | else 58 | returnError(INV_B32_DATA, 0); 59 | 60 | value = (value << 5) + c; 61 | bits += 5; 62 | 63 | if (bits >= 8) 64 | { 65 | *(binary + outOffset) = (char) (value >> (bits - 8)); 66 | bits -= 8; 67 | value = value % (1 << bits); 68 | outOffset++; 69 | } 70 | } 71 | offset += 8; 72 | } 73 | return outOffset; 74 | } 75 | 76 | // convert a binary buffer to a Base32 string 77 | 78 | size_t binaryToBase32(char *binary, size_t binarySize, char *base32, size_t base32Size) 79 | { 80 | size_t offset = 0; 81 | size_t outOffset = 0; 82 | 83 | if (binarySize % 5) 84 | returnError(INV_B32_ENC_SIZE, 0); 85 | if ((binarySize * 8 / 5) > base32Size) 86 | returnError(BUF_TOO_SMALL, 0); 87 | while (offset < binarySize && outOffset < base32Size) 88 | { 89 | int bits = 0; 90 | int value = 0; 91 | 92 | for (int i = 0; i < 5; i++) 93 | { 94 | value = (value << 8) + (*(binary + offset + i) & 0xFF); 95 | bits += 8; 96 | while (bits >= 5) 97 | { 98 | *(base32 + outOffset) = base32Table[(value >> (bits - 5))]; 99 | bits -= 5; 100 | value = value % (1 << bits); 101 | outOffset++; 102 | } 103 | } 104 | offset += 5; 105 | } 106 | return outOffset; 107 | } 108 | -------------------------------------------------------------------------------- /src/base32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef BASE32_H 23 | 24 | #define BASE32_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | size_t base32ToBinary(char *base32, size_t base32Size, char *binary, size_t binarySize); 31 | size_t binaryToBase32(char *binary, size_t binarySize, char *base32, size_t base32Size); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef BASE64_H 23 | 24 | #define BASE64_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | size_t base64ToBinary(char *base64, size_t base64Size, char *binary, size_t binarySize, bool pad, bool ignoreWhitespace); 31 | size_t binaryToBase64(char *binary, size_t binarySize, char *base64, size_t base64Size, bool pad); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/checksum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef CHECKSUM_H 23 | 24 | #define CHECKSUM_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void checksum_usage(const bool help, const bool version); 31 | int checksum_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef CHECKSUM_C 34 | 35 | extern commandEntry_t * checksum_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/checksum_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void checksum_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program computes the CRC-32 value for a FRITZ!OS export file.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-d, --all-data", "compute value over the 'raw' input file, don't handle the different parts of an export file", 0); 48 | addOptionsEntry("-x, --hex-output", "show the computed value as hexadecimal string on STDOUT, otherwise it's written as decimal string", 0); 49 | addOptionsEntry("-r, --raw-output", "write the 32 bits of the computed value as binary data to STDOUT (host order)", 0); 50 | addOptionsEntry("-l, --lsb-output", "write the 32 bits of the computed value as binary data to STDOUT (LSB order)", 0); 51 | addOptionsEntry("-m, --msb-output", "write the 32 bits of the computed value as binary data to STDOUT (MSB order)", 0); 52 | addOptionsEntryVerbose(); 53 | addOptionsEntryQuiet(); 54 | addOptionsEntryStrict(); 55 | addOptionsEntryHelp(); 56 | addOptionsEntryVersion(); 57 | showOptionsEnd(out); 58 | 59 | fprintf(out, 60 | "\nUsually the input data is expected to be an export file from FRITZ!OS. In this case, the CRC-32\n" 61 | "value is re-computed over the different parts of this export file and replaced at the last line of\n" 62 | "input data, while the whole file is copied to STDOUT.\n" 63 | ); 64 | 65 | fprintf(out, 66 | "\nIf you specify any of the output options, the value is still recomputed, but input data will not\n" 67 | "be copied to STDOUT and only the CRC-32 value will be written to STDOUT using the specified format.\n" 68 | ); 69 | 70 | fprintf(out, 71 | "\nIf the '--all-data' option (or '-d') was specified, input data will not be handled as export file\n" 72 | "and the CRC-32 value will be computed over the 'raw content'. Output format options are used to set\n" 73 | "the format of data on STDOUT, input data will never be copied to STDOUT." 74 | ); 75 | 76 | showUsageFinalize(out, help, version); 77 | } 78 | 79 | char * checksum_shortdesc(void) 80 | { 81 | return "compute checksum on STDIN data"; 82 | } 83 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef COMMON_H 23 | 24 | #define COMMON_H 25 | 26 | #define _GNU_SOURCE 27 | 28 | #define EXPORTED __attribute__((__visibility__("default"), used, externally_visible)) 29 | #define UNUSED __attribute__((unused)) 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #ifdef NETTLE 46 | 47 | #include 48 | #include 49 | #include 50 | 51 | #include "crypto_nettle.h" 52 | 53 | #else 54 | 55 | #include 56 | 57 | #include "crypto_ossl.h" 58 | 59 | #endif 60 | 61 | #include "config.h" 62 | #include "errors.h" 63 | 64 | #include "base32.h" 65 | #include "base64.h" 66 | #include "hex.h" 67 | #include "crc32.h" 68 | 69 | #include "functions.h" 70 | #include "memory.h" 71 | #include "output.h" 72 | #include "help.h" 73 | #include "license.h" 74 | #include "options.h" 75 | #include "environ.h" 76 | 77 | #include "encryption.h" 78 | #include "exportfile.h" 79 | 80 | #include "b32dec.h" 81 | #include "b32enc.h" 82 | #include "b64dec.h" 83 | #include "b64enc.h" 84 | #include "hexdec.h" 85 | #include "hexenc.h" 86 | #include "userpw.h" 87 | #include "devpw.h" 88 | #include "pwfrdev.h" 89 | #include "decsngl.h" 90 | #include "decfile.h" 91 | #include "decexp.h" 92 | #include "deccb.h" 93 | #include "pkpwd.h" 94 | #include "checksum.h" 95 | #include "decompose.h" 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/config.in: -------------------------------------------------------------------------------- 1 | /* 2 | * vim: set tabstop=4 syntax=c : 3 | * 4 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program, please look for the file LICENSE. 18 | */ 19 | 20 | #ifndef CONFIG_H 21 | 22 | #define CONFIG_H 23 | 24 | // configuration area 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/crc32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define CRC32_C 23 | 24 | #include "common.h" 25 | 26 | EXPORTED crcCtx_t * crcInit(void) 27 | { 28 | crcCtx_t *ctx = malloc(sizeof(crcCtx_t)); 29 | 30 | memset(ctx, 0, sizeof(crcCtx_t)); 31 | 32 | for (uint32_t i = 0; i < (sizeof(ctx->table) / sizeof(uint32_t)); i++) 33 | { 34 | uint32_t v = i; 35 | 36 | for (uint32_t j = 0; j < 8; j++) 37 | { 38 | bool o = ((v & 1) == 1); 39 | 40 | v >>= 1; 41 | if (o) 42 | v ^= CRC_POLYNOM; 43 | } 44 | ctx->table[i] = v; 45 | } 46 | 47 | ctx->value = ~(ctx->value); 48 | 49 | return ctx; 50 | } 51 | 52 | EXPORTED void crcUpdate(crcCtx_t * ctx, const char * input, const size_t size) 53 | { 54 | uint8_t byte; 55 | 56 | if (!ctx) 57 | return; 58 | 59 | for (size_t i = 0; i < size; i++) 60 | { 61 | byte = *(input + i); 62 | ctx->value = (ctx->value >> 8) ^ ctx->table[(ctx->value & 255) ^ byte]; 63 | } 64 | } 65 | 66 | EXPORTED uint32_t crcFinal(crcCtx_t * ctx) 67 | { 68 | uint32_t value; 69 | 70 | if (!ctx) 71 | return 0; 72 | 73 | value = ~(ctx->value); 74 | 75 | free(ctx); 76 | 77 | return value; 78 | } 79 | -------------------------------------------------------------------------------- /src/crc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef CRC32_H 23 | 24 | #define CRC32_H 25 | 26 | #include "common.h" 27 | 28 | #define CRC_POLYNOM 0xEDB88320 29 | 30 | // CRC context 31 | 32 | typedef struct crcCtx { 33 | uint32_t value; 34 | uint32_t table[256]; 35 | } crcCtx_t; 36 | 37 | // function prototypes 38 | 39 | crcCtx_t * crcInit(void); 40 | void crcUpdate(crcCtx_t * ctx, const char * input, const size_t size); 41 | uint32_t crcFinal(crcCtx_t * ctx); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/crypto_nettle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define CRYPTO_C 23 | 24 | #include "common.h" 25 | 26 | // static variables 27 | 28 | static size_t __cipher_keyLen = -1; 29 | static size_t __cipher_ivLen = -1; 30 | static size_t __cipher_blockSize = -1; 31 | static size_t __digest_blockSize = -1; 32 | EXPORTED size_t *cipher_keyLen = &__cipher_keyLen; 33 | EXPORTED size_t *cipher_ivLen = &__cipher_ivLen; 34 | EXPORTED size_t *cipher_blockSize = &__cipher_blockSize; 35 | EXPORTED size_t *digest_blockSize = &__digest_blockSize; 36 | 37 | // cipher functions 38 | 39 | // various size settings 40 | 41 | EXPORTED void CipherSizes() 42 | { 43 | *cipher_keyLen = AES256_KEY_SIZE; 44 | *cipher_ivLen = AES_BLOCK_SIZE; 45 | *cipher_blockSize = AES_BLOCK_SIZE; 46 | } 47 | 48 | EXPORTED void CryptoCleanup(void) 49 | { 50 | return; 51 | } 52 | 53 | EXPORTED CipherContext * CipherContextNew(void) 54 | { 55 | CipherContext * ctx = malloc(sizeof(CipherContext)); 56 | 57 | if (!ctx) 58 | return NULL; 59 | 60 | memset(ctx, 0, sizeof(CipherContext)); 61 | ctx->cipher_mode = CipherTypeValue; 62 | 63 | return ctx; 64 | } 65 | 66 | // initialize a cipher context 67 | 68 | EXPORTED CipherContext * CipherInit(CipherContext * ctx, CipherMode mode, char * key, char * iv, UNUSED bool padding) 69 | { 70 | CipherContext *cipherCTX = NULL; 71 | 72 | if (ctx) 73 | { 74 | if (key && iv) /* reset context first */ 75 | { 76 | memset(ctx, 0, sizeof(CipherContext)); 77 | cipherCTX = ctx; 78 | } 79 | } 80 | else 81 | { 82 | cipherCTX = CipherContextNew(); 83 | 84 | if (!cipherCTX) 85 | returnError(OSSL_CIPHER_ERR, NULL); 86 | } 87 | 88 | if (!key && !iv) 89 | return cipherCTX; 90 | 91 | aes256_set_decrypt_key(&(cipherCTX->cbc_context.ctx), (uint8_t *) key); 92 | cipherCTX->cipher_mode = mode; 93 | if (mode == CipherTypeValue) 94 | CBC_SET_IV(&(cipherCTX->cbc_context), iv); 95 | 96 | return cipherCTX; 97 | } 98 | 99 | // cleanup a context and free the used memory 100 | 101 | EXPORTED CipherContext * CipherCleanup(CipherContext * ctx) 102 | { 103 | if (!ctx) 104 | return NULL; 105 | 106 | memset(ctx, 0, sizeof(CipherContext)); 107 | free(ctx); 108 | 109 | return NULL; 110 | } 111 | 112 | // update a CBC context 113 | 114 | EXPORTED bool CipherUpdate(CipherContext * ctx, char *output, size_t *outputSize, char *input, size_t inputSize) 115 | { 116 | if (!ctx) 117 | return false; 118 | 119 | // if (*outputSize < inputSize) 120 | // { 121 | // setError(BUF_TOO_SMALL); 122 | // return false; 123 | // } 124 | 125 | size_t inSize = (inputSize - (inputSize % *cipher_blockSize)); 126 | 127 | if (ctx->cipher_mode == CipherTypeValue) 128 | { 129 | CBC_DECRYPT(&(ctx->cbc_context), aes256_decrypt, inSize, (uint8_t *) output, (uint8_t *) input); 130 | *outputSize = inSize; 131 | } 132 | else 133 | { 134 | aes256_decrypt(&(ctx->cbc_context.ctx), inSize, (uint8_t *) output, (uint8_t *) input); 135 | *outputSize = inSize; 136 | } 137 | 138 | return true; 139 | } 140 | 141 | // finalize a decryption 142 | 143 | EXPORTED bool CipherFinal(CipherContext * ctx, UNUSED char *output, UNUSED size_t *outputSize) 144 | { 145 | if (!ctx) 146 | return false; 147 | 148 | *outputSize = 0; 149 | 150 | return true; 151 | } 152 | 153 | // digest functions 154 | 155 | // get digest value length 156 | 157 | EXPORTED void DigestSizes() 158 | { 159 | *digest_blockSize = MD5_DIGEST_SIZE; 160 | } 161 | 162 | // initialize a digest context 163 | 164 | EXPORTED DigestContext * DigestInit() 165 | { 166 | DigestContext * ctx; 167 | 168 | ctx = malloc(sizeof(DigestContext)); 169 | if (!ctx) 170 | setError(OSSL_DIGEST_ERR); 171 | else 172 | md5_init(ctx); 173 | return ctx; 174 | } 175 | 176 | // update a digest context from the specified buffer 177 | 178 | EXPORTED bool DigestUpdate(DigestContext * ctx, char * buffer, size_t bufferSize) 179 | { 180 | if (!ctx) 181 | return false; 182 | 183 | md5_update(ctx, bufferSize, (const uint8_t *) buffer); 184 | 185 | return true; 186 | } 187 | 188 | // finalize a digest value 189 | 190 | EXPORTED bool DigestFinal(DigestContext * ctx, char * output) 191 | { 192 | if (!ctx) 193 | return false; 194 | 195 | md5_digest(ctx, *digest_blockSize, (uint8_t *) output); 196 | return true; 197 | } 198 | 199 | // cleanup a digest context, free resources 200 | 201 | EXPORTED DigestContext * DigestCleanup(DigestContext * ctx) 202 | { 203 | if (!ctx) 204 | return NULL; 205 | memset(ctx, 0, sizeof(DigestContext)); 206 | free(ctx); 207 | return NULL; 208 | } 209 | 210 | // compute and return a digest value for the specified buffer, all context handling 211 | // is encapsulated 212 | 213 | EXPORTED size_t Digest(char *buffer, size_t bufferSize, char *digest, size_t digestSize) 214 | { 215 | resetError(); 216 | 217 | DigestContext *ctx = DigestInit(); 218 | 219 | if (isAnyError()) 220 | return false; 221 | 222 | if (digestSize < *digest_blockSize) 223 | setError(BUF_TOO_SMALL); 224 | else 225 | { 226 | if (DigestUpdate(ctx, buffer, bufferSize)) 227 | { 228 | DigestFinal(ctx, digest); 229 | } 230 | } 231 | ctx = DigestCleanup(ctx); 232 | 233 | return (isAnyError() ? 0 : *digest_blockSize); 234 | } 235 | -------------------------------------------------------------------------------- /src/crypto_nettle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef CRYPTO_H 23 | 24 | #define CRYPTO_H 25 | 26 | #include "common.h" 27 | 28 | // Nettle types 29 | 30 | typedef enum { 31 | CipherTypeValue, /* use CBC mode */ 32 | CipherTypeFile, /* use ECB mode */ 33 | } CipherMode; 34 | 35 | typedef struct { 36 | struct CBC_CTX(struct aes256_ctx, AES_BLOCK_SIZE) cbc_context; 37 | CipherMode cipher_mode; 38 | } CipherContext; 39 | 40 | #define DigestContext struct md5_ctx 41 | #define MAX_DIGEST_SIZE MD5_DIGEST_SIZE 42 | 43 | #ifndef CRYPTO_C 44 | 45 | // various sizes 46 | 47 | extern size_t * cipher_keyLen; 48 | extern size_t * cipher_ivLen; 49 | extern size_t * cipher_blockSize; 50 | extern size_t * digest_blockSize; 51 | 52 | #endif 53 | 54 | // cipher and digest functions 55 | 56 | void CipherSizes(); 57 | CipherContext * CipherInit(CipherContext * ctx, CipherMode mode, char * key, char * iv, bool padding); 58 | CipherContext * CipherCleanup(CipherContext * ctx); 59 | bool CipherUpdate(CipherContext * ctx, char *output, size_t *outputSize, char *input, size_t inputSize); 60 | bool CipherFinal(CipherContext * ctx, char *output, size_t *outputSize); 61 | 62 | void DigestSizes(void); 63 | DigestContext * DigestInit(); 64 | DigestContext * DigestCleanup(DigestContext * ctx); 65 | bool DigestUpdate(DigestContext * ctx, char * buffer, size_t bufferSize); 66 | bool DigestFinal(DigestContext * ctx, char * output); 67 | size_t Digest(char *buffer, size_t bufferSize, char *digest, size_t digestSize); 68 | 69 | void CryptoCleanup(void); 70 | CipherContext * CipherContextNew(void); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/crypto_ossl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define CRYPTO_C 23 | 24 | #include "common.h" 25 | 26 | // static variables 27 | 28 | static size_t __cipher_keyLen = -1; 29 | static size_t __cipher_ivLen = -1; 30 | static size_t __cipher_blockSize = -1; 31 | static size_t __digest_blockSize = -1; 32 | EXPORTED size_t *cipher_keyLen = &__cipher_keyLen; 33 | EXPORTED size_t *cipher_ivLen = &__cipher_ivLen; 34 | EXPORTED size_t *cipher_blockSize = &__cipher_blockSize; 35 | EXPORTED size_t *digest_blockSize = &__digest_blockSize; 36 | 37 | // cipher functions 38 | 39 | // various size settings 40 | 41 | EXPORTED void CipherSizes() 42 | { 43 | *cipher_keyLen = EVP_CIPHER_key_length(EVP_aes_256_cbc()); 44 | *cipher_ivLen = EVP_CIPHER_iv_length(EVP_aes_256_cbc()); 45 | *cipher_blockSize = EVP_CIPHER_block_size(EVP_aes_256_cbc()); 46 | } 47 | 48 | // EVP functions encapsulated 49 | 50 | EXPORTED void CryptoCleanup(void) 51 | { 52 | EVP_cleanup(); 53 | } 54 | 55 | EXPORTED CipherContext * CipherContextNew(void) 56 | { 57 | return EVP_CIPHER_CTX_new(); 58 | } 59 | 60 | // initialize a cipher context 61 | 62 | EXPORTED CipherContext * CipherInit(CipherContext * ctx, CipherMode mode, char * key, char * iv, bool padding) 63 | { 64 | CipherContext *cipherCTX = NULL; 65 | 66 | if (ctx) 67 | { 68 | if (key && iv) /* reset context first */ 69 | { 70 | cipherCTX = ctx; 71 | EVP_CIPHER_CTX_init(cipherCTX); 72 | } 73 | } 74 | else 75 | { 76 | cipherCTX = CipherContextNew(); 77 | if (!cipherCTX) 78 | returnError(OSSL_CIPHER_ERR, NULL); 79 | } 80 | if (!key && !iv) 81 | return cipherCTX; 82 | if (EVP_DecryptInit_ex(cipherCTX, (mode == CipherTypeValue ? EVP_aes_256_cbc() : EVP_aes_256_ecb()), NULL, (unsigned char *) key, (unsigned char *) iv)) 83 | { 84 | EVP_CIPHER_CTX_set_padding(cipherCTX, padding); 85 | return cipherCTX; 86 | } 87 | returnError(OSSL_CIPHER_ERR, NULL); 88 | } 89 | 90 | // cleanup a context and free the used memory 91 | 92 | EXPORTED CipherContext * CipherCleanup(CipherContext * ctx) 93 | { 94 | if (!ctx) 95 | return NULL; 96 | EVP_CIPHER_CTX_cleanup(ctx); 97 | EVP_CIPHER_CTX_free(ctx); 98 | return NULL; 99 | } 100 | 101 | // update a CBC context 102 | 103 | EXPORTED bool CipherUpdate(CipherContext * ctx, char *output, size_t *outputSize, char *input, size_t inputSize) 104 | { 105 | if (!ctx) 106 | return false; 107 | if (!EVP_DecryptUpdate(ctx, (unsigned char *) output, (int *) outputSize, (unsigned char *) input, inputSize)) 108 | { 109 | setError(OSSL_CIPHER_ERR); 110 | return false; 111 | } 112 | return true; 113 | } 114 | 115 | // finalize a decryption 116 | 117 | EXPORTED bool CipherFinal(CipherContext * ctx, char *output, size_t *outputSize) 118 | { 119 | if (!ctx) 120 | return false; 121 | if (!EVP_DecryptFinal_ex(ctx, (unsigned char *) output, (int *) outputSize)) 122 | { 123 | setError(OSSL_CIPHER_ERR); 124 | return false; 125 | } 126 | return true; 127 | } 128 | 129 | // digest functions 130 | 131 | // get digest value length 132 | 133 | EXPORTED void DigestSizes() 134 | { 135 | *digest_blockSize = EVP_MD_size(EVP_md5()); 136 | } 137 | 138 | // initialize a digest context 139 | 140 | EXPORTED DigestContext * DigestInit() 141 | { 142 | DigestContext *ctx = EVP_MD_CTX_create(); 143 | 144 | if (!ctx) 145 | setError(OSSL_DIGEST_ERR); 146 | else 147 | { 148 | if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) 149 | { 150 | setError(OSSL_DIGEST_ERR); 151 | EVP_MD_CTX_destroy(ctx); 152 | ctx = NULL; 153 | } 154 | } 155 | return ctx; 156 | } 157 | 158 | // update a digest context from the specified buffer 159 | 160 | EXPORTED bool DigestUpdate(DigestContext * ctx, char * buffer, size_t bufferSize) 161 | { 162 | if (!ctx) 163 | return false; 164 | if (!EVP_DigestUpdate(ctx, buffer, bufferSize)) 165 | { 166 | setError(OSSL_DIGEST_ERR); 167 | return false; 168 | } 169 | return true; 170 | } 171 | 172 | // finalize a digest value 173 | 174 | EXPORTED bool DigestFinal(DigestContext * ctx, char * output) 175 | { 176 | if (!ctx) 177 | return false; 178 | if (!EVP_DigestFinal_ex(ctx, (unsigned char *) output, NULL)) 179 | { 180 | setError(OSSL_DIGEST_ERR); 181 | return false; 182 | } 183 | return true; 184 | } 185 | 186 | // cleanup a digest context, free resources 187 | 188 | EXPORTED DigestContext * DigestCleanup(DigestContext * ctx) 189 | { 190 | if (!ctx) 191 | return NULL; 192 | EVP_MD_CTX_destroy(ctx); 193 | return NULL; 194 | } 195 | 196 | // compute and return a digest value for the specified buffer, all context handling 197 | // is encapsulated 198 | 199 | EXPORTED size_t Digest(char *buffer, size_t bufferSize, char *digest, size_t digestSize) 200 | { 201 | resetError(); 202 | 203 | DigestContext *ctx = DigestInit(); 204 | 205 | if (isAnyError()) 206 | return false; 207 | 208 | if (digestSize < *digest_blockSize) 209 | setError(BUF_TOO_SMALL); 210 | else 211 | { 212 | if (DigestUpdate(ctx, buffer, bufferSize)) 213 | { 214 | DigestFinal(ctx, digest); 215 | } 216 | } 217 | ctx = DigestCleanup(ctx); 218 | 219 | return (isAnyError() ? 0 : *digest_blockSize); 220 | } 221 | -------------------------------------------------------------------------------- /src/crypto_ossl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef CRYPTO_H 23 | 24 | #define CRYPTO_H 25 | 26 | #include "common.h" 27 | 28 | // EVP types 29 | 30 | #define CipherContext EVP_CIPHER_CTX 31 | #define DigestContext EVP_MD_CTX 32 | #define MAX_DIGEST_SIZE EVP_MAX_MD_SIZE 33 | 34 | typedef enum { 35 | CipherTypeValue, /* use CBC mode */ 36 | CipherTypeFile, /* use ECB mode */ 37 | } CipherMode; 38 | 39 | #ifndef CRYPTO_C 40 | 41 | // various sizes 42 | 43 | extern size_t * cipher_keyLen; 44 | extern size_t * cipher_ivLen; 45 | extern size_t * cipher_blockSize; 46 | extern size_t * digest_blockSize; 47 | 48 | #endif 49 | 50 | // cipher and digest functions 51 | 52 | void CipherSizes(); 53 | CipherContext * CipherInit(CipherContext * ctx, CipherMode mode, char * key, char * iv, bool padding); 54 | CipherContext * CipherCleanup(CipherContext * ctx); 55 | bool CipherUpdate(CipherContext * ctx, char *output, size_t *outputSize, char *input, size_t inputSize); 56 | bool CipherFinal(CipherContext * ctx, char *output, size_t *outputSize); 57 | 58 | void DigestSizes(void); 59 | DigestContext * DigestInit(); 60 | DigestContext * DigestCleanup(DigestContext * ctx); 61 | bool DigestUpdate(DigestContext * ctx, char * buffer, size_t bufferSize); 62 | bool DigestFinal(DigestContext * ctx, char * output); 63 | size_t Digest(char *buffer, size_t bufferSize, char *digest, size_t digestSize); 64 | 65 | void CryptoCleanup(void); 66 | CipherContext * CipherContextNew(void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/deccb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECCB_H 23 | 24 | #define DECCB_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void deccb_usage(const bool help, const bool version); 31 | int deccb_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef DECCB_C 34 | 35 | extern commandEntry_t * deccb_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/deccb_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void deccb_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program expects the encoded content (using a hexadecimal (default) or Base64 encoding) of an\n" 39 | "encrypted file entry from an export file and tries to decrypt it. If decryption was possible, the\n" 40 | "clear-text data will be written to STDOUT.\n" 41 | ); 42 | 43 | showFormatHeader(out); 44 | addSpace(); 45 | addOption("options"); 46 | addSpace(); 47 | endOptions(); 48 | addSpace(); 49 | addNormalString("{ "); 50 | addArgument("password"); 51 | addAlternative(); 52 | addArgument("serial"); 53 | addSpace(); 54 | addArgument("maca"); 55 | addNormalString(" }"); 56 | showFormatEnd(out); 57 | 58 | showOptionsHeader("options"); 59 | addOptionsEntry("-t, --tty", "don't quit execution, if STDIN is connected to a terminal device", 0); 60 | addOptionsEntry("-n, --b64-input", "input file contains Base64 encoded data (FRITZ!OS 07.19 and above)", 0); 61 | addOptionsEntry("-b, --bin-input", "input file contains raw binary data", 0); 62 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 63 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) for textual output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 64 | addOptionsEntry("-a, --alt-env " __undl("filename"), "use an alternative source for the 'urlader environment'", 8); 65 | addOptionsEntryVerbose(); 66 | addOptionsEntryQuiet(); 67 | addOptionsEntryStrict(); 68 | addOptionsEntryHelp(); 69 | addOptionsEntryVersion(); 70 | showOptionsEnd(out); 71 | 72 | fprintf(out, 73 | "\nThe input data has to be extracted from the body of an encrypted file entry (CRPYTEDBINFILE or -\n" 74 | "starting with FRITZ!OS 07.19 - CRYPTEDB64FILE) - that means, the lines (starting with asterisks)\n" 75 | "around the encoded lines have to be removed already.\n" 76 | "If the input file contains binary data without encoding, use the 'bin-input' (or 'b') option." 77 | ); 78 | 79 | fprintf(out, 80 | "\nIf the export file was created with a %s, this %s must be specified as the only\n" 81 | "parameter. If no %s was used to export the settings, there are two alternatives to specify\n" 82 | "the two needed properties of the source device. You can use the second form of parameters with\n" 83 | "%s and %s set to the correct values or you can use an alternative file for the 'urlader\n" 84 | "environment' (using the '--alt-env' (or '-a') option) and the program will extract the values there.\n", 85 | showUndl("password"), showUndl("password"), showUndl("password"), 86 | showUndl("serial"), showUndl("maca") 87 | ); 88 | 89 | fprintf(out, 90 | "\nIf a file was created without a password, there are two alternatives to specify the two needed\n" 91 | "properties of the source device. You can use the second form of parameters with %s and %s set\n" 92 | "to the correct values or you can use an alternative file for the 'urlader environment' (using the\n" 93 | "'--alt-env' (or '-a') option from above) and the program will extract the values there.\n" 94 | "\nAn alternative environment file is ignored, if the first format with %s is used.\n", 95 | showUndl("serial"), showUndl("maca"), showUndl("password") 96 | ); 97 | 98 | fprintf(out, 99 | "\nIf the content can not be decrypted (decrypted raw data contain 16 bytes at the end, where we can\n" 100 | "check a successful decryption), nothing is written to STDOUT. Without any further options, output\n" 101 | "data will be written in 'raw' format - that means, the decrypted content will be written 'as is'.\n" 102 | "This could be a problem with binary files and you may specify the '--hex-output' (or '-x') option\n" 103 | "to output data with hexadecimal encoding. If you use this option, you can force lines with limited\n" 104 | "width using the '--wrap-lines' (or '-w') option. Optionally you can set your wanted line width too.\n" 105 | ); 106 | 107 | fprintf(out, 108 | "\nIf the '--tty' option wasn't specified and STDIN is a terminal device, then the execution will be\n" 109 | "aborted. The last value from command-line will NOT be checked, if it's a valid file name.\n" 110 | ); 111 | 112 | showUsageFinalize(out, help, version); 113 | } 114 | 115 | char * deccb_shortdesc(void) 116 | { 117 | return "decrypt encrypted data sections from an export file"; 118 | } 119 | -------------------------------------------------------------------------------- /src/decexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECEXP_H 23 | 24 | #define DECEXP_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void decexp_usage(const bool help, UNUSED const bool version); 31 | int decexp_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef DECEXP_C 34 | 35 | extern commandEntry_t * decexp_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/decfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECFILE_H 23 | 24 | #define DECFILE_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void decfile_usage(const bool help, const bool version); 31 | int decfile_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef DECFILE_C 34 | 35 | extern commandEntry_t * decfile_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/decfile_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void decfile_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program decrypts all occurrences of encrypted data on STDIN (if decryption is possible) and\n" 39 | "writes the data to STDOUT, while replacing cipher-text with the corresponding clear-text values.\n" 40 | ); 41 | 42 | showFormatHeader(out); 43 | addSpace(); 44 | addOption("options"); 45 | addSpace(); 46 | endOptions(); 47 | addSpace(); 48 | startOption(); 49 | addArgument("parameter"); 50 | addSpace(); 51 | startOption(); 52 | addNormalString("..."); 53 | endOption(); 54 | endOption(); 55 | addSpace(); 56 | startOption(); 57 | startOption(); 58 | addNormalString("<"); 59 | endOption(); 60 | addSpace(); 61 | addArgument("input-file"); 62 | endOption(); 63 | showFormatEnd(out); 64 | 65 | showOptionsHeader("options"); 66 | addOptionsEntry("-t, --tty", "don't quit execution, if STDIN is connected to a terminal device", 0); 67 | addOptionsEntry("-a, --alt-env " __undl("filename"), "use an alternative source for the 'urlader environment'", 8); 68 | addOptionsEntry("-l, --low-memory", "do not try to consolidate input data into a single buffer", 0); 69 | addOptionsEntry("-b, --block-size " __undl("size"), "read input data in blocks of the specified " __undl("size"), 8); 70 | addOptionsEntryVerbose(); 71 | addOptionsEntryQuiet(); 72 | addOptionsEntryStrict(); 73 | addOptionsEntryHelp(); 74 | addOptionsEntryVersion(); 75 | showOptionsEnd(out); 76 | 77 | fprintf(out, 78 | "\nThe %s may be any text file, starting from a real TFFS node up to a single line of Base32\n" 79 | "encoded cipher-text, as long as any encrypted value starts with the four dollar-signs. This can be\n" 80 | "useful, if you extract some settings from a configuration file with other utilities (e.g.\n" 81 | "'ar7cfgctl') and want to decode only a single value or a smaller amount of values.\n", 82 | showUndl("input-file") 83 | ); 84 | 85 | fprintf(out, 86 | "\nSTDIN has to be redirected or the program will be aborted - it's a protection against accidental\n" 87 | "calls without proper redirection, otherwise the program would block the caller. If you really want\n" 88 | "to call it with STDIN connected to a terminal device, specify the '--tty' option for the call.\n\n" 89 | "If STDIN is connected to a terminal device and the '--tty' option (or '-t') wasn't specified, the\n" 90 | "last expected value from command line is checked, wether it's the name of a readable file. In this\n" 91 | "case the specified %s will be used as source of input data.\n", 92 | showUndl("input-file") 93 | ); 94 | 95 | fprintf(out, 96 | "\nThe number of %ss depends on the mode of the call. If no %s was specified, the\n" 97 | "decryption key is built from device properties in the 'urlader environment'. If the program isn't\n" 98 | "called on a FRITZ!OS device, the 'urlader environment' may be substituted by a text file. Its\n" 99 | "location can be specified with the '--alt-env' (or '-a') option.\n", 100 | showUndl("parameter"), showUndl("parameter") 101 | ); 102 | 103 | fprintf(out, 104 | "\nIf a single %s is used, it has to be a hexadecimal string representing the key to be used\n" 105 | "for decryption.\n", 106 | showUndl("parameter") 107 | ); 108 | 109 | fprintf(out, 110 | "\nIf more than one %s exists, it's an alternative approach to decrypt data from another\n" 111 | "FRITZ!OS device with knowledge of its properties - this one doesn't need an environment file\n" 112 | "from somewhere. For this mode, you need at least the '%s', '%s' and '%s' values\n" 113 | "of the foreign device. If it has a pre-configured CWMP account, you need the value from the field\n" 114 | "'%s' of the device too.\n", 115 | showUndl("parameter"), showUndl(URLADER_SERIAL_NAME), showUndl(URLADER_MACA_NAME), 116 | showUndl(URLADER_WLANKEY_NAME), showUndl(URLADER_TR069PP_NAME) 117 | ); 118 | 119 | fprintf(out, 120 | "\nIf you've got a copy of the 'urlader environment' for the device, where your %s was\n" 121 | "created, you should use this file with the '--alt-env' option instead of specifying three and more\n" 122 | "values for the call.\n", 123 | showUndl("input-file") 124 | ); 125 | 126 | fprintf(out, 127 | "\nThe option '--low-memory' (or '-l') may be used, if your system has not enough free memory to hold\n" 128 | "the input data (from really huge files) twice in memory for a short time.\n" 129 | ); 130 | 131 | fprintf(out, 132 | "\nThe option '--block-size' (or '-b') to specify the input block size should seldom be necessary. If\n" 133 | "you specify it, you can set a buffer size between 32 bytes and 16 Mbytes. Any valid number may be\n" 134 | "followed by a 'K' or 'M' (upper or lower case) to use a factor of 2**10 or 2**20 with the given\n" 135 | "number. This disables at the same time all further tries to consolidate the input data in a single\n" 136 | "buffer (as if the option '--low-memory' was used).\n" 137 | ); 138 | 139 | showUsageFinalize(out, help, version); 140 | } 141 | 142 | char * decfile_shortdesc(void) 143 | { 144 | return "decrypt Base32 encoded secrets from an input file"; 145 | } 146 | -------------------------------------------------------------------------------- /src/decoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define DECODER_C 23 | 24 | #include "decoder.h" 25 | #include "decoder_usage.c" 26 | 27 | #ifdef _WIN32 28 | #include "windows.h" 29 | #endif 30 | 31 | #pragma GCC diagnostic push 32 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 33 | #pragma GCC diagnostic ignored "-Wformat-security" 34 | 35 | // main entry point for each call 36 | 37 | int main(int argc, char** argv) 38 | { 39 | int argumentCount = argc; 40 | char ** arguments = argv; 41 | int argumentOffset = 0; 42 | char * fname = NULL; 43 | char * ename = NULL; 44 | 45 | #ifdef _WIN32 46 | // Enable VT processing for the escape sequences on Windows 47 | DWORD cmode; 48 | HANDLE hcon; 49 | 50 | hcon = GetStdHandle(STD_OUTPUT_HANDLE); 51 | if (hcon != INVALID_HANDLE_VALUE) 52 | { 53 | if (GetConsoleMode(hcon, &cmode)) 54 | { 55 | SetConsoleMode(hcon, cmode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); 56 | } 57 | } 58 | 59 | // No "applet" support on Windows 60 | ename = basename(strdup(arguments[0])); 61 | fname = strdup(ename); 62 | argumentOffset = 0; 63 | #else 64 | char enameLong[PATH_MAX+1]; 65 | size_t linkSize; 66 | 67 | if ((linkSize = readlink("/proc/self/exe", enameLong, PATH_MAX)) == (size_t) -1) 68 | { 69 | errorMessage(errorExecutableName); 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | enameLong[PATH_MAX] = 0; 74 | enameLong[linkSize] = 0; 75 | if (argumentCount == 0) 76 | { 77 | errorMessage(errorInvocationName); 78 | exit(EXIT_FAILURE); 79 | } 80 | ename = basename(strdup(enameLong)); 81 | fname = basename(strdup(arguments[0])); 82 | 83 | if (strcmp(ename, fname)) 84 | { 85 | argumentOffset = 0; 86 | } 87 | else 88 | #endif 89 | if (argumentCount > 1 && *(arguments[1]) != '-') 90 | { 91 | fname = arguments[1]; 92 | argumentOffset = 1; 93 | } 94 | else 95 | { 96 | setAppletName(fname); 97 | if (argc > 1) 98 | { 99 | int opt; 100 | int optIndex = 0; 101 | 102 | static struct option options_long[] = { 103 | { "help", no_argument, NULL, 'h' }, 104 | { "version", no_argument, NULL, 'V' }, 105 | options_long_end, 106 | }; 107 | char * options_short = ":hV"; 108 | 109 | while ((opt = getopt_long(argc, argv, options_short, options_long, &optIndex)) != -1) 110 | { 111 | switch (opt) 112 | { 113 | case 'h': 114 | main_usage(true, false); 115 | #if DEBUG == 1 116 | fprintf(stdout, "====> applet list - only visible on DEBUG builds <====\n"); 117 | int i = 0; 118 | commandEntry_t *current = getCommandEntry(i); 119 | 120 | while (current) 121 | { 122 | char * *name = *(current->names); 123 | 124 | fprintf(stdout, "ep=0x%08llx, usage=0x%08llx, usesCrypto=%u, finalNewlineOnTTY=%u, name=", \ 125 | (long long unsigned int) current->ep, (long long unsigned int) current->usage, \ 126 | current->usesCrypto, current->finalNewlineOnTTY); 127 | 128 | while (*name) 129 | { 130 | fprintf(stdout, "%s ", *name); 131 | name++; 132 | } 133 | fprintf(stdout, "\n"); 134 | current = getCommandEntry(++i); 135 | } 136 | #endif 137 | return EXIT_SUCCESS; 138 | 139 | case 'V': 140 | main_usage(false, true); 141 | return EXIT_SUCCESS; 142 | 143 | getopt_invalid_option(); 144 | invalid_option(opt); 145 | } 146 | } 147 | } 148 | 149 | main_usage(false, false); 150 | 151 | exit(EXIT_FAILURE); 152 | } 153 | 154 | int i=0; 155 | commandEntry_t * current = getCommandEntry(i); 156 | 157 | while (current) 158 | { 159 | char * * name = *(current->names); 160 | 161 | while (*name) 162 | { 163 | if (!strcmp(fname, *name)) 164 | { 165 | if (current->usesCrypto) encryptionInit(); 166 | arguments[0] = ename; 167 | opterr = 0; 168 | setAppletName(*name); 169 | int exitCode = (*current->ep)(argumentCount, arguments, argumentOffset, current); 170 | if (exitCode == EXIT_SUCCESS) 171 | { 172 | if (current->finalNewlineOnTTY && isatty(1) && !isAnyError()) 173 | fprintf(stdout, "\n"); 174 | } 175 | if (current->usesCrypto) CryptoCleanup(); 176 | exit(exitCode); 177 | } 178 | name++; 179 | } 180 | current = getCommandEntry(++i); 181 | } 182 | 183 | if (!current) 184 | { 185 | setAppletName(ename); 186 | #ifdef _WIN32 187 | errorMessage(errorInvalidFunction, fname); 188 | #else 189 | errorMessage(errorInvalidFunction, fname, enameLong); 190 | #endif 191 | main_usage(false, false); 192 | } 193 | 194 | exit(EXIT_FAILURE); 195 | } 196 | 197 | #pragma GCC diagnostic pop 198 | -------------------------------------------------------------------------------- /src/decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECODER_H 23 | 24 | #define DECODER_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void main_usage(const bool help, const bool version); 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /src/decoder_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 26 | #pragma GCC diagnostic ignored "-Wformat-security" 27 | 28 | void main_usage(const bool help, const bool version) 29 | { 30 | FILE * out = (help || version ? stdout : stderr); 31 | 32 | showUsageHeader(out, help, version); 33 | 34 | if (version) 35 | { 36 | fprintf(out, "\n"); 37 | return; 38 | } 39 | 40 | showPurposeHeader(out); 41 | #ifdef _WIN32 42 | fprintf(out, 43 | "This program is a 'multi-call' binary. Its function is selected by the first argument on\n" 44 | "the command-line.\n" 45 | "\nLet's call these functions 'applets' from now on, like BusyBox does it.\n" 46 | ); 47 | #else 48 | fprintf(out, 49 | "This program is a 'multi-call' binary. Its function is either selected by the first argument on\n" 50 | "the command-line or by the name of the (hard or symbolic) link, which is used to call it.\n" 51 | "\nLet's call these functions 'applets' from now on, like BusyBox does it.\n" 52 | ); 53 | #endif 54 | 55 | showFormatHeader(out); 56 | addSpace(); 57 | addNormalString("{ "); 58 | addArgument("options"); 59 | addAlternative(); 60 | addArgument("applet"); 61 | addSpace(); 62 | addOption("parameters"); 63 | addNormalString(" }"); 64 | showFormatEnd(out); 65 | 66 | showOptionsHeader("options"); 67 | addOptionsEntryHelp(); 68 | addOptionsEntryVersion(); 69 | showOptionsEnd(out); 70 | 71 | fprintf(out, 72 | "\nThe %s names are configurable at build time, the available names and their purposes are shown\n" 73 | "below.\n" 74 | "\nAny applicable %s rely on the wanted %s and are shown, if you call an %s with the\n" 75 | "'--help' (or '-h') option.\n", 76 | showUndl("applet"), showUndl("parameters"), showUndl("applet"), showUndl("applet") 77 | ); 78 | 79 | fprintf(out, 80 | "\nConfigured %s and their names are:\n", 81 | showUndl("applets") 82 | ); 83 | 84 | int i = 0; 85 | size_t left = 0; 86 | size_t right = 0; 87 | size_t leftFill = 0; 88 | commandEntry_t *current = getCommandEntry(i); 89 | char * *name; 90 | bool moreThanOneName = false; 91 | bool multiLine = false; 92 | 93 | while (current) 94 | { 95 | name = *(current->names); 96 | moreThanOneName = false; 97 | 98 | while (*name) 99 | { 100 | if ((strlen(*name) + (moreThanOneName ? 3 : 0)) > left) 101 | { 102 | left = strlen(*name) + (moreThanOneName ? 3 : 0); 103 | } 104 | name++; 105 | moreThanOneName = true; 106 | } 107 | if (strlen((*current->short_desc)()) > right) 108 | right = strlen((*current->short_desc)()); 109 | current = getCommandEntry(++i); 110 | } 111 | 112 | leftFill = left; 113 | fprintf(out, "\napplet"); 114 | leftFill -= 6; 115 | for (size_t j = 0; j < leftFill; j++) 116 | { 117 | fprintf(out, " "); 118 | } 119 | fprintf(out, " purpose\n"); 120 | 121 | if ((left + 3 + right) > 99) 122 | right = 99 - (left + 3); 123 | 124 | for (size_t j = 0; j < (left + 3 + right); j++) 125 | fprintf(out, "="); 126 | 127 | fprintf(out, "\n"); 128 | 129 | i = 0; 130 | current = getCommandEntry(i); 131 | 132 | while (current) 133 | { 134 | leftFill = left; 135 | fprintf(out, "\n"); 136 | name = *(current->names); 137 | fprintf(out, "%s", showBold(*name)); 138 | leftFill -= strlen(*name); 139 | name++; 140 | if (*name) 141 | { 142 | fprintf(out, " or"); 143 | leftFill -= 3; 144 | } 145 | for (size_t j = 0; j < leftFill; j++) 146 | { 147 | fprintf(out, " "); 148 | } 149 | fprintf(out, " - "); 150 | 151 | char * desc = (*current->short_desc)(); 152 | char * last; 153 | char * next; 154 | 155 | if (strlen(desc) > right) 156 | { 157 | last = desc + right; 158 | while (!isspace(*last)) 159 | last--; 160 | next = last; 161 | while (isspace(*last)) 162 | last--; 163 | fwrite(desc, last - desc + 1, 1, out); 164 | desc = next; 165 | multiLine = true; 166 | } 167 | else 168 | { 169 | fprintf(out, "%s", desc); 170 | multiLine = false; 171 | } 172 | while (*name || multiLine) 173 | { 174 | size_t leftUsed = 0; 175 | 176 | if (*name) 177 | { 178 | fprintf(out, "\n"); 179 | fprintf(out, "%s", showBold(*name)); 180 | leftUsed += strlen(*name); 181 | name++; 182 | if (*name) 183 | { 184 | fprintf(out, " or"); 185 | leftUsed += 3; 186 | } 187 | } 188 | if (multiLine) 189 | { 190 | if (leftUsed == 0) 191 | fprintf(out, "\n"); 192 | for (size_t j = leftUsed; j < (left + 2); j++) 193 | { 194 | fprintf(out, " "); 195 | } 196 | if (strlen(desc) > right) 197 | { 198 | last = desc + right; 199 | while (!isspace(*last)) 200 | last--; 201 | next = last; 202 | while (isspace(*last)) 203 | last--; 204 | 205 | fwrite(desc, last - desc + 1, 1, out); 206 | desc = next; 207 | multiLine = true; 208 | } 209 | else 210 | { 211 | fprintf(out, "%s", desc); 212 | multiLine = false; 213 | } 214 | } 215 | } 216 | current = getCommandEntry(++i); 217 | fprintf(out, "\n" ); 218 | } 219 | 220 | showUsageFinalize(out, help, version); 221 | } 222 | 223 | #pragma GCC diagnostic pop 224 | -------------------------------------------------------------------------------- /src/decompose.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define DECOMPOSE_C 23 | 24 | #include "common.h" 25 | #include "decompose_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "decompose_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __decompose_command = { .names = &commandNames, .ep = &decompose_entry, .short_desc = &decompose_shortdesc, .usage = &decompose_usage }; 37 | EXPORTED commandEntry_t * decompose_command = &__decompose_command; 38 | 39 | // 'decompose' function - split an export file into single files 40 | 41 | int decompose_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | char * outputDir = NULL; 44 | struct stat fileStat; 45 | bool withDictionary = false; 46 | 47 | if (argc > argo + 1) 48 | { 49 | int opt; 50 | int optIndex = 0; 51 | 52 | static struct option options_long[] = { 53 | { "output-directory", required_argument, NULL, 'o' }, 54 | { "dictionary", required_argument, NULL, 'd' }, 55 | verbosity_options_long, 56 | options_long_end, 57 | }; 58 | char * options_short = ":" "o:d" verbosity_options_short; 59 | 60 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 61 | { 62 | switch (opt) 63 | { 64 | case 'o': 65 | { 66 | if (!optarg) 67 | { 68 | errorMessage(errorMissingDirectoryName); 69 | setError(OPTION_VALUE_MISSING); 70 | return EXIT_FAILURE; 71 | } 72 | outputDir = strdup(optarg); 73 | } 74 | break; 75 | 76 | case 'd': 77 | withDictionary = true; 78 | break; 79 | 80 | check_verbosity_options_short(); 81 | help_option(); 82 | getopt_invalid_option(); 83 | invalid_option(opt); 84 | } 85 | } 86 | if (optind < argc) 87 | warnAboutExtraArguments(argv, optind + 1); 88 | } 89 | 90 | if (isatty(0)) 91 | { 92 | errorMessage(errorNoReadFromTTY); 93 | return EXIT_FAILURE; 94 | } 95 | 96 | if (!outputDir) 97 | { 98 | errorMessage(errorMissingDirectoryName); 99 | setError(OPTION_VALUE_MISSING); 100 | return EXIT_FAILURE; 101 | } 102 | 103 | if (stat(outputDir, &fileStat) != 0 || !S_ISDIR(fileStat.st_mode)) 104 | { 105 | errorMessage(errorInvalidDirectoryName, outputDir); 106 | setError(OPTION_VALUE_INVALID); 107 | } 108 | 109 | if (isAnyError()) 110 | return EXIT_FAILURE; 111 | 112 | resetError(); 113 | 114 | memoryBuffer_t *inputFile = memoryBufferReadFile(stdin, -1); 115 | 116 | if (!inputFile) 117 | { 118 | if (!isAnyError()) /* empty input file */ 119 | { 120 | errorMessage(errorEmptyInputFile); 121 | } 122 | else 123 | { 124 | errorMessage(errorReadToMemory); 125 | } 126 | return EXIT_FAILURE; 127 | } 128 | 129 | memoryBuffer_t *consolidated = memoryBufferConsolidateData(inputFile); 130 | 131 | if (!consolidated) 132 | { 133 | errorMessage(errorNoMemory); 134 | inputFile = memoryBufferFreeChain(inputFile); 135 | return EXIT_FAILURE; 136 | } 137 | else 138 | { 139 | inputFile = memoryBufferFreeChain(inputFile); 140 | inputFile = consolidated; 141 | verboseMessage(verboseInputDataConsolidated, memoryBufferDataSize(inputFile)); 142 | } 143 | 144 | decomposeExportFile(inputFile, outputDir, withDictionary); 145 | 146 | memoryBufferFreeChain(inputFile); 147 | 148 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 149 | } 150 | 151 | #pragma GCC diagnostic pop 152 | -------------------------------------------------------------------------------- /src/decompose.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECOMPOSE_H 23 | 24 | #define DECOMPOSE_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void decompose_usage(const bool help, const bool version); 31 | int decompose_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef CHECKSUM_C 34 | 35 | extern commandEntry_t * decompose_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/decompose_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void decompose_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program splits a single export file into the settings files contained therein.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-o, --output " __undl("directory"), "specifies the " __undl("directory") ", where the files will be stored; this option is mandatory (and therefore not really an option)", 8); 48 | addOptionsEntry("-d, --dictionary", "create a dictionary file and store header data separately", 0); 49 | addOptionsEntryVerbose(); 50 | addOptionsEntryQuiet(); 51 | addOptionsEntryStrict(); 52 | addOptionsEntryHelp(); 53 | addOptionsEntryVersion(); 54 | showOptionsEnd(out); 55 | 56 | fprintf(out, 57 | "\nThe file with exported FRITZ!OS settings is expected on STDIN. Execution will be aborted, if STDIN\n" 58 | "is a terminal device.\n" 59 | ); 60 | 61 | fprintf(out, 62 | "\nThe output directory has to exist. Any data file therein may be overwritten without further warning.\n" 63 | "\nIf you want to create a new file to be imported from the decomposed export file, you may specify the\n" 64 | "'--dictionary' (or '-d') option to store the original header lines and a list of all contained files,\n" 65 | "preserving their order.\n" 66 | ); 67 | 68 | showUsageFinalize(out, help, version); 69 | } 70 | 71 | char * decompose_shortdesc(void) 72 | { 73 | return "split an export file, with optional decryption"; 74 | } 75 | -------------------------------------------------------------------------------- /src/decsngl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DECSNGL_H 23 | 24 | #define DECSNGL_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void decsngl_usage(const bool help, const bool version); 31 | int decsngl_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef DECSNGL_C 34 | 35 | extern commandEntry_t * decsngl_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/decsngl_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void decsngl_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program takes a Base32 encoded value and a hexadecimal key and tries to decrypt the value.\n" 39 | "If decryption was possible, the clear-text data will be written to STDOUT.\n" 40 | ); 41 | 42 | showFormatHeader(out); 43 | addSpace(); 44 | addOption("options"); 45 | addSpace(); 46 | endOptions(); 47 | addSpace(); 48 | addArgument("cipher-text"); 49 | addSpace(); 50 | addArgument("key"); 51 | showFormatEnd(out); 52 | 53 | showOptionsHeader("options"); 54 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 55 | addOptionsEntryVerbose(); 56 | addOptionsEntryQuiet(); 57 | addOptionsEntryStrict(); 58 | addOptionsEntryHelp(); 59 | addOptionsEntryVersion(); 60 | showOptionsEnd(out); 61 | 62 | fprintf(out, 63 | "\nThe %s parameter must be a Base32 encoded value (using AVM's 'digits', but without the\n" 64 | "leading dollar-signs); its size is verified and has to be a multiple of eight.\n", 65 | showUndl("cipher-text") 66 | ); 67 | 68 | fprintf(out, 69 | "\nThe %s argument is a hexadecimal string for the decryption key to use and it has to contain 64 or\n" 70 | "32 characters; values with 32 characters are padded with zeros to a 256-bit key.\n", 71 | showUndl("key") 72 | ); 73 | 74 | fprintf(out, 75 | "\nIf the decoded data doesn't look like a C-string (that means, the last byte isn't NUL), the decoded\n" 76 | "data will be output as a hexadecimal string, prefixed with '0x' to mark this format. If hexadecimal\n" 77 | "output was requested with option '--hex-output' (or '-x'), this marker is omitted. There's no way\n" 78 | "to distinguish between the forced output as hexadecimal string and a value, which really starts\n" 79 | "with '0x'. If hexadecimal output is used, any NUL character isn't removed from the end of the data.\n" 80 | ); 81 | 82 | showUsageFinalize(out, help, version); 83 | } 84 | 85 | char * decsngl_shortdesc(void) 86 | { 87 | return "decrypt Base32 encoded data using a specified AES key"; 88 | } 89 | -------------------------------------------------------------------------------- /src/devpw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define DEVPW_C 23 | 24 | #include "common.h" 25 | #include "devpw_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "devpw_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __devpw_command = { .names = &commandNames, .ep = &devpw_entry, .usage = &devpw_usage, .short_desc = &devpw_shortdesc, .usesCrypto = true }; 37 | EXPORTED commandEntry_t * devpw_command = &__devpw_command; 38 | 39 | // 'device_password' function - compute the password hash from the specified device properties 40 | 41 | int devpw_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | bool hexOutput = false; 44 | char hash[MAX_DIGEST_SIZE]; 45 | size_t hashLen = sizeof(hash); 46 | char hex[(sizeof(hash) * 2) + 1]; 47 | size_t hexLen = 0; 48 | char * out; 49 | size_t outLen; 50 | char * serial = NULL; 51 | char * maca = NULL; 52 | char * wlanKey = NULL; 53 | char * tr069Passphrase = NULL; 54 | 55 | if (argc > argo + 1) 56 | { 57 | int opt; 58 | int optIndex = 0; 59 | 60 | static struct option options_long[] = { 61 | verbosity_options_long, 62 | { "hex-output", no_argument, NULL, 'x' }, 63 | options_long_end, 64 | }; 65 | char * options_short = ":" "x" verbosity_options_short; 66 | 67 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 68 | { 69 | switch (opt) 70 | { 71 | case 'x': 72 | hexOutput = true; 73 | break; 74 | 75 | check_verbosity_options_short(); 76 | help_option(); 77 | getopt_invalid_option(); 78 | invalid_option(opt); 79 | } 80 | } 81 | if (optind >= (argc - argo)) 82 | { 83 | errorMessage(errorMissingArguments); 84 | __autoUsage(); 85 | return EXIT_FAILURE; 86 | } 87 | else 88 | { 89 | int i = optind + argo; 90 | int index = 0; 91 | 92 | char * *arguments[] = { 93 | &serial, 94 | &maca, 95 | &wlanKey, 96 | &tr069Passphrase, 97 | NULL 98 | }; 99 | 100 | while (argv[i]) 101 | { 102 | *(arguments[index++]) = argv[i++]; 103 | if (!arguments[index]) 104 | break; 105 | } 106 | if (!maca) 107 | { 108 | errorMessage(errorMissingSerialMac); 109 | __autoUsage(); 110 | return EXIT_FAILURE; 111 | } 112 | if (argv[i]) 113 | { 114 | warnAboutExtraArguments(argv, i); 115 | } 116 | } 117 | } 118 | else 119 | { 120 | errorMessage(errorMissingArguments); 121 | __autoUsage(); 122 | return EXIT_FAILURE; 123 | } 124 | 125 | if (isAnyError()) 126 | return EXIT_FAILURE; 127 | 128 | resetError(); 129 | 130 | if (keyFromProperties(hash, &hashLen, serial, maca, wlanKey, tr069Passphrase)) 131 | { 132 | hexLen = binaryToHexadecimal((char *) hash, hashLen, hex, sizeof(hex)); 133 | hex[hexLen] = 0; 134 | verboseMessage(verboseDeviceKeyHash, hex); 135 | 136 | if (!isAnyError() && !hexOutput && isatty(1)) 137 | { 138 | if (fwrite("0x", 2, 1, stdout) != 1) 139 | { 140 | setError(WRITE_FAILED); 141 | errorMessage(errorWriteFailed); 142 | } 143 | hexOutput = true; 144 | } 145 | 146 | if (!isAnyError()) 147 | { 148 | if (hexOutput) 149 | { 150 | outLen = hexLen; 151 | out = hex; 152 | entry->finalNewlineOnTTY = true; 153 | } 154 | else 155 | { 156 | outLen = hashLen; 157 | out = (char *) hash; 158 | } 159 | if (fwrite(out, outLen, 1, stdout) != 1) 160 | { 161 | setError(WRITE_FAILED); 162 | errorMessage(errorWriteFailed); 163 | } 164 | } 165 | } 166 | 167 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 168 | } 169 | 170 | #pragma GCC diagnostic pop 171 | -------------------------------------------------------------------------------- /src/devpw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef DEVPW_H 23 | 24 | #define DEVPW_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void devpw_usage(const bool help, const bool version); 31 | int devpw_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef DEVPW_C 34 | 35 | extern commandEntry_t * devpw_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/devpw_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void devpw_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program takes up to four parameters from the command line (each of them stands for a property\n" 39 | "from the 'urlader environment' of a FRITZ!OS device) and generates a device-specific encryption key\n" 40 | "from their values.\n" 41 | ); 42 | 43 | showFormatHeader(out); 44 | addSpace(); 45 | addOption("options"); 46 | addSpace(); 47 | endOptions(); 48 | addSpace(); 49 | addArgument("prop1"); 50 | addSpace(); 51 | addArgument("prop2"); 52 | addSpace(); 53 | startOption(); 54 | addArgument("prop3"); 55 | addSpace(); 56 | startOption(); 57 | addArgument("prop4"); 58 | endOption(); 59 | endOption(); 60 | showFormatEnd(out); 61 | 62 | showOptionsHeader("options"); 63 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 64 | addOptionsEntryVerbose(); 65 | addOptionsEntryQuiet(); 66 | addOptionsEntryStrict(); 67 | addOptionsEntryHelp(); 68 | addOptionsEntryVersion(); 69 | showOptionsEnd(out); 70 | 71 | fprintf(out, 72 | "\nThe following properties are needed to create a valid key:\n" 73 | ); 74 | 75 | fprintf(out, 76 | "\n%s is the serial number of the device, it consists of 15 characters and can be found at the\n" 77 | "back of the device, together with other info printed on a sticker. But for a long time this serial\n" 78 | "number was only printed there and only the latest models contain this value in a place, where it\n" 79 | "can be read by the firmware. All older models used a character string of 16 zeros here. You have to\n" 80 | "know, what value your device really uses - but you could try both approaches, if you've problems\n" 81 | "with a key version. The correct value can be found as %s in a support-data file or in an\n" 82 | "environment dump.\n", 83 | showUndl("prop1"), showUndl(URLADER_SERIAL_NAME) 84 | ); 85 | 86 | fprintf(out, 87 | "\n%s is the value of the %s field from environment and it's used as Ethernet address (MAC) on\n" 88 | "the LAN side of a FRITZ!OS device. Its format is also well-known (6 groups of two hexadecimal digits\n" 89 | "(upper-case for A to Z), separated by colons) and the program verifies the format to ensure it's\n" 90 | "valid.\n", 91 | showUndl("prop2"), showUndl(URLADER_MACA_NAME) 92 | ); 93 | 94 | fprintf(out, 95 | "\nThe %s value is the content of the pre-defined WLAN key (%s) from factory-settings and it\n" 96 | "can be found on the sticker too. It consists of 16 or 20 digits and the program verifies the\n" 97 | "expected format.\n", 98 | showUndl("prop3"), showUndl(URLADER_WLANKEY_NAME) 99 | ); 100 | 101 | fprintf(out, 102 | "\nThe %s value is only used, if the device in question is equipped with a CWMP account in its\n" 103 | "factory settings. Then the content of the %s entry is added to the computation of a\n" 104 | "device-specific key.\n", 105 | showUndl("prop4"), showUndl(URLADER_TR069PP_NAME) 106 | ); 107 | 108 | fprintf(out, 109 | "\nThe third and fourth arguments (%s and %s) are optional (and the latter\n" 110 | "value may be missing on a device). If a device-specific key is intended to encrypt settings\n" 111 | "export files, FRITZ!OS versions will use only the first two properties to compute the key value.\n", 112 | showUndl(URLADER_WLANKEY_NAME), showUndl(URLADER_TR069PP_NAME) 113 | ); 114 | 115 | fprintf(out, 116 | "\nThe computed key will be written to STDOUT; if the option '--hex-output' (or '-x') was specified,\n" 117 | "output data will be converted to a hexadecimal string. If STDOUT is connected to a terminal device,\n" 118 | "hexadecimal output is activated automatically. As long as the option for hexadecimal output wasn't\n" 119 | "selected explicitely, the value will get a prefix '0x' in front of it.\n" 120 | ); 121 | 122 | showUsageFinalize(out, help, version); 123 | } 124 | 125 | char * devpw_shortdesc(void) 126 | { 127 | return "compute a secret key based on specified device properties"; 128 | } 129 | -------------------------------------------------------------------------------- /src/encryption.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef ENCRYPTION_H 23 | 24 | #define ENCRYPTION_H 25 | 26 | #include "common.h" 27 | 28 | // FRITZ!OS environment related settings 29 | 30 | #define URLADER_SERIAL_NAME "SerialNumber" 31 | #define URLADER_MACA_NAME "maca" 32 | #define URLADER_WLANKEY_NAME "wlan_key" 33 | #define URLADER_TR069PP_NAME "tr069_passphrase" 34 | 35 | #define EXPORT_PASSWORD_NAME "\nPassword=$$$$" 36 | #define EXPORT_PASSWORD2_NAME "\nPassword2=$$$$" 37 | 38 | #define PRIVKEY_PASSWORD_SIZE 8 39 | 40 | // decrytion related functions 41 | 42 | void encryptionInit(void); 43 | 44 | bool digestCheckValue(char *buffer, size_t bufferSize, char * *value, size_t * dataLen, bool * string); 45 | 46 | bool decryptValue(CipherContext * ctx, char * cipherText, size_t cipherTextSize, FILE * out, char * outBuffer, char * key, bool escaped); 47 | bool decryptFile(char * input, size_t inputSize, FILE * out, char * outBuffer, char * key, bool hexOutput); 48 | 49 | bool keyFromDevice(char * hash, size_t * hashSize, bool forExport); 50 | bool keyFromProperties(char * hash, size_t * hashSize, char * serial, char * maca, char * wlanKey, char * tr069Passphrase); 51 | 52 | bool privateKeyPassword(char * out, size_t * outLen, char * maca); 53 | 54 | bool checkMACAddress(char * mac); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/environ.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define ENVIRON_C 23 | 24 | #include "common.h" 25 | 26 | #pragma GCC diagnostic push 27 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 28 | #pragma GCC diagnostic ignored "-Wformat-security" 29 | 30 | // environment file name 31 | 32 | static char * environmentFileName = URLADER_ENV_PATH; 33 | 34 | // get/set environment file name 35 | 36 | EXPORTED void setEnvironmentPath(char * path) 37 | { 38 | environmentFileName = strdup(path); 39 | } 40 | 41 | EXPORTED char * getEnvironmentPath(void) 42 | { 43 | return strdup(environmentFileName); 44 | } 45 | 46 | EXPORTED memoryBuffer_t * getEnvironmentFile(void) 47 | { 48 | FILE * environment = fopen(environmentFileName, "r"); 49 | 50 | if (!environment) 51 | { 52 | errorMessage(errorOpeningEnvironment, environmentFileName); 53 | setError(URLADER_ENV_ERR); 54 | return NULL; 55 | } 56 | 57 | // 2 KByte are usually enough room for an environment ... if it's 58 | // really too small, consolidation takes place later 59 | 60 | memoryBuffer_t * env = memoryBufferReadFile(environment, 2048); 61 | 62 | fclose(environment); 63 | 64 | if (!env) 65 | { 66 | errorMessage(errorReadingEnvironment, environmentFileName); 67 | setError(URLADER_ENV_ERR); 68 | return false; 69 | } 70 | 71 | if (env->next) 72 | { 73 | memoryBuffer_t *new = memoryBufferConsolidateData(env); 74 | memoryBufferFreeChain(env); 75 | env = new; 76 | } 77 | 78 | size_t offset = 0; 79 | 80 | // replace newlines with end of strings for easier access 81 | 82 | while (offset < env->used) 83 | { 84 | if (*(env->data + offset) == '\n') 85 | *(env->data + offset) = 0; 86 | offset++; 87 | } 88 | 89 | return env; 90 | } 91 | 92 | EXPORTED char * getEnvironmentValue(memoryBuffer_t * environ, char * name) 93 | { 94 | memoryBuffer_t * env = (environ ? environ : getEnvironmentFile()); 95 | 96 | if (!env) 97 | return NULL; 98 | 99 | char * current = env->data; 100 | char * value = NULL; 101 | 102 | while (current < (env->data + env->used)) 103 | { 104 | if (!strncmp(current, name, strlen(name))) 105 | { 106 | if (*(current + strlen(name)) == '\t') 107 | { 108 | value = strdup(current + strlen(name) + 1); 109 | break; 110 | } 111 | } 112 | current += strlen(current) + 1; 113 | } 114 | 115 | if (!environ) 116 | memoryBufferFreeChain(env); 117 | 118 | return value; 119 | } 120 | 121 | #pragma GCC diagnostic pop 122 | -------------------------------------------------------------------------------- /src/environ.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef ENVIRON_H 23 | 24 | #define ENVIRON_H 25 | 26 | #include "common.h" 27 | 28 | // FRITZ!OS environment related settings 29 | 30 | #define URLADER_ENV_PATH DECODER_CONFIG_URLADER_ENVIRONMENT_PATH 31 | 32 | // environment file functions 33 | 34 | char * getEnvironmentPath(void); 35 | void setEnvironmentPath(char * path); 36 | 37 | memoryBuffer_t * getEnvironmentFile(void); 38 | char * getEnvironmentValue(memoryBuffer_t * environ, char * name); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef ERRORS_H 23 | 24 | #define ERRORS_H 25 | 26 | // named error codes 27 | 28 | typedef enum { 29 | // no error 30 | DECODER_ERROR_NOERROR = 0, 31 | // error writing data to file 32 | DECODER_ERROR_WRITE_FAILED, 33 | // buffer too small for output data 34 | DECODER_ERROR_BUF_TOO_SMALL, 35 | // error allocating memory 36 | DECODER_ERROR_NO_MEMORY, 37 | // invalid Base32 character 38 | DECODER_ERROR_INV_B32_DATA, 39 | // invalid size of Base32 encoded string 40 | DECODER_ERROR_INV_B32_SIZE, 41 | // invalid Base64 character 42 | DECODER_ERROR_INV_B64_DATA, 43 | // invalid size of Base64 encoded string 44 | DECODER_ERROR_INV_B64_SIZE, 45 | // invalid size of data to encode (must be a multiple of 5) 46 | DECODER_ERROR_INV_B32_ENC_SIZE, 47 | // invalid size of data to encode (must be a multiple of 3 without padding) 48 | DECODER_ERROR_INV_B64_ENC_SIZE, 49 | // invalid hexadecimal characters 50 | DECODER_ERROR_INV_HEX_DATA, 51 | // invalid hexadecimal data size 52 | DECODER_ERROR_INV_HEX_SIZE, 53 | // invalid decipher key was specified 54 | DECODER_ERROR_INVALID_KEY, 55 | // error returned from an OpenSSL cipher function 56 | DECODER_ERROR_OSSL_CIPHER_ERR, 57 | // error returned from an OpenSSL digest function 58 | DECODER_ERROR_OSSL_DIGEST_ERR, 59 | // error reading STDIN file into memory buffers 60 | DECODER_ERROR_STDIN_BUFFER_ERR, 61 | // error opening/reading device environment on a FRITZ!OS device 62 | DECODER_ERROR_URLADER_ENV_ERR, 63 | // error decrypting a file with the specified arguments 64 | DECODER_ERROR_DECRYPT_ERR, 65 | // STDIN file looks invalid and not like an export file 66 | DECODER_ERROR_INVALID_FILE, 67 | // invalid length of second stage key entry 68 | DECODER_ERROR_INV_DATA_SIZE, 69 | // warning treated as error due to '--strict' option set 70 | DECODER_ERROR_WARNING_ISSUED, 71 | // unable to read a value from 'urlader environment' 72 | DECODER_ERROR_ENV_VALUE_MISSING, 73 | // invalid buffer size specified 74 | DECODER_ERROR_INV_BUF_SIZE, 75 | // conflicting options specified 76 | DECODER_ERROR_OPTIONS_CONFLICT, 77 | // missing option value 78 | DECODER_ERROR_OPTION_VALUE_MISSING, 79 | // invalid option value 80 | DECODER_ERROR_OPTION_VALUE_INVALID, 81 | // I/O error encountered 82 | DECODER_ERROR_IO_ERROR, 83 | } decoder_error_t; 84 | 85 | #ifndef ERRORS_C 86 | 87 | // global error text definitions 88 | 89 | extern char * *__decoder_error_text; 90 | 91 | // global error state 92 | 93 | extern decoder_error_t * __decoder_error; 94 | 95 | // error messages 96 | 97 | extern char * errorAccessingEnvironment; 98 | extern char * errorDecryptFileData; 99 | extern char * errorDecryptionFailed; 100 | extern char * errorDeviceProperties; 101 | extern char * errorDigestComputation; 102 | extern char * errorExecutableName; 103 | extern char * errorInvalidArgumentData; 104 | extern char * errorInvalidDataSize; 105 | extern char * errorInvalidFirstStageLength; 106 | extern char * errorInvalidFunction; 107 | extern char * errorInvalidHexSize; 108 | extern char * errorInvalidHexValue; 109 | extern char * errorInvalidKeyValue; 110 | extern char * errorInvalidValue; 111 | extern char * errorInvalidWidth; 112 | extern char * errorInvocationName; 113 | extern char * errorMissingArguments; 114 | extern char * errorMissingSerialMac; 115 | extern char * errorNoMemory; 116 | extern char * errorNoPasswordEntry; 117 | extern char * errorPasswordMissing; 118 | extern char * errorReadToMemory; 119 | extern char * errorUnexpectedError; 120 | extern char * errorWriteFailed; 121 | extern char * errorWrongArgumentsCount; 122 | extern char * errorWrongHexKeyLength; 123 | extern char * errorWrongKeySize; 124 | extern char * errorWrongPassword; 125 | extern char * errorMissingDeviceProperty; 126 | extern char * errorOpeningEnvironment; 127 | extern char * errorReadingEnvironment; 128 | extern char * errorInvalidOption; 129 | extern char * errorMissingOptionValue; 130 | extern char * errorInvalidOrAmbiguousOption; 131 | extern char * errorReadFromTTY; 132 | extern char * errorNoReadFromTTY; 133 | extern char * errorWrongMACAddress; 134 | extern char * errorInvalidBufferSize; 135 | extern char * errorConflictingOptions; 136 | extern char * errorEmptyInputFile; 137 | extern char * errorNoConsolidate; 138 | extern char * errorMissingDirectoryName; 139 | extern char * errorInvalidDirectoryName; 140 | extern char * errorUnexpectedIOError; 141 | 142 | #endif 143 | 144 | // function prototypes 145 | 146 | char * getErrorText(decoder_error_t err); 147 | 148 | // helper macros 149 | 150 | #define setError(err) *__decoder_error = DECODER_ERROR_##err 151 | 152 | #define resetError() setError(NOERROR) 153 | 154 | #define returnError(err,value) { setError(err); return (value); } 155 | 156 | #define getError() (*__decoder_error) 157 | 158 | #define isAnyError() (getError() != DECODER_ERROR_NOERROR) 159 | 160 | #define isError(err) (getError() == DECODER_ERROR_##err) 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /src/exportfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef CHKSUM_H 23 | 24 | #define CHKSUM_H 25 | 26 | #include "common.h" 27 | 28 | // FRITZ!OS export file checksum routines 29 | 30 | uint32_t computeExportFileChecksum(memoryBuffer_t * input, FILE * out); 31 | void decomposeExportFile(memoryBuffer_t * input, const char * path, bool readyForComposition); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/functions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define FUNCTIONS_C 23 | 24 | #include "common.h" 25 | 26 | // callable functions table 27 | 28 | commandEntry_t ** commandsTable[] = { 29 | #include "applets.h" 30 | NULL 31 | }; 32 | 33 | commandEntry_t * getCommandEntry(int index) 34 | { 35 | if (!commandsTable[index]) return NULL; 36 | return *(commandsTable[index]); 37 | }; 38 | -------------------------------------------------------------------------------- /src/functions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef FUNCTIONS_H 23 | 24 | #define FUNCTIONS_H 25 | 26 | #include "common.h" 27 | 28 | // data types for internal routing to requested function 29 | 30 | typedef struct commandEntry commandEntry_t; 31 | 32 | struct commandEntry { 33 | char * * *names; 34 | int (*ep)(int argc, char **argv, int argo, commandEntry_t * entry); 35 | void (*usage)(const bool help, const bool version); 36 | char * (*short_desc)(void); 37 | bool usesCrypto; 38 | bool finalNewlineOnTTY; 39 | }; 40 | 41 | #ifndef FUNCTIONS_C 42 | 43 | // function table 44 | 45 | extern commandEntry_t * *commandsTable; 46 | 47 | #endif 48 | 49 | // function definitions 50 | 51 | commandEntry_t * getCommandEntry(int index); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/help.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef HELP_H 23 | 24 | #define HELP_H 25 | 26 | typedef struct showOption { 27 | struct showOption * next; 28 | char * value; 29 | size_t invisible; 30 | char * description; 31 | } showOption_t; 32 | 33 | #define DECODER_MAIN_VERSION "0.4" 34 | #define DECODER_HELP_WIDTH 99 35 | 36 | #define __undl(string) "\033[4m" string "\033[0m" 37 | // Mingw seems to be missing __STRING(x) 38 | #ifndef __STRING 39 | #define __STRING(x) #x 40 | #endif 41 | #define STRING(number) __STRING(number) 42 | 43 | void showUsageHeader(FILE * out, const bool help, const bool version); 44 | void showUsageFinalize(FILE * out, const bool help, const bool version); 45 | void showVersion(FILE * out, const bool help); 46 | void showPurposeHeader(FILE * out); 47 | void showFormatHeader(FILE * out); 48 | void addArgument(const char * arg); 49 | void addNormalString(const char * arg); 50 | void addOption(const char * option); 51 | void startOption(void); 52 | void endOption(void); 53 | void endOptions(void); 54 | void addSpace(void); 55 | void addAlternative(void); 56 | void showFormatEnd(FILE * out); 57 | void showOptionsHeader(char * option); 58 | void addOptionsEntry(char * value, char * description, size_t invisible); 59 | void addOptionsEntryVerbose(void); 60 | void addOptionsEntryHelp(void); 61 | void addOptionsEntryVersion(void); 62 | void addOptionsEntryVerbose(void); 63 | void addOptionsEntryQuiet(void); 64 | void addOptionsEntryStrict(void); 65 | void buildOptionsDisplay(void); 66 | void showOptionsEnd(FILE * out); 67 | char * showBold(const char * data); 68 | char * showUndl(const char * data); 69 | void addIndent(void); 70 | void removeIndent(void); 71 | char * getIndent(char * prefix, char * suffix); 72 | char * newLine(void); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/hex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #include "hex.h" 23 | 24 | // hexadecimal translation table 25 | 26 | static char * UNUSED hexTable = "0123456789ABCDEF"; 27 | 28 | // hexadecimal conversion functions 29 | 30 | // convert a hexadecimal string to a binary buffer 31 | 32 | size_t hexadecimalToBinary(char *input, size_t inputSize, char *output, size_t outputSize) 33 | { 34 | size_t offset = 0; 35 | size_t outOffset = 0; 36 | size_t inSize = (inputSize == (size_t) -1 ? strlen(input) : inputSize); 37 | int value = 0; 38 | bool high = true; 39 | 40 | if ((inSize / 2) > outputSize) 41 | returnError(BUF_TOO_SMALL, (inSize / 2)); 42 | while (offset < inSize && outOffset < outputSize) 43 | { 44 | char c = *(input + offset++) & 0xFF; 45 | 46 | if (c >= 'A' && c <= 'F') 47 | { 48 | c = c - 'A' + 10; 49 | } 50 | else if (c >= 'a' && c <= 'f') 51 | { 52 | c = c - 'a' + 10; 53 | } 54 | else if (c >= '0' && c <= '9') 55 | { 56 | c -= '0'; 57 | } 58 | else if (isspace(c)) 59 | continue; 60 | else 61 | { 62 | returnError(INV_HEX_DATA, 0); 63 | } 64 | if (high) 65 | { 66 | value = c << 4; 67 | high = false; 68 | } 69 | else 70 | { 71 | value = value + c; 72 | high = true; 73 | *(output + outOffset++) = value; 74 | } 75 | } 76 | if (!high) 77 | returnError(INV_HEX_SIZE, 0); 78 | return outOffset; 79 | } 80 | 81 | // convert a binary buffer to a hexadecimal string 82 | 83 | size_t binaryToHexadecimal(char *input, size_t inputSize, char *output, size_t outputSize) 84 | { 85 | size_t index = 0; 86 | 87 | if ((inputSize * 2) > (outputSize - 1)) 88 | returnError(BUF_TOO_SMALL, (inputSize * 2)); 89 | while ((index < inputSize) && ((index * 2) < (outputSize - 1))) 90 | { 91 | *(output + (index * 2)) = hexTable[(((*(input + index)) >> 4) & 0x0F)]; 92 | *(output + (index * 2) + 1) = hexTable[((*(input + index)) & 0x0F)]; 93 | index++; 94 | } 95 | return (index * 2); 96 | } 97 | -------------------------------------------------------------------------------- /src/hex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef HEX_H 23 | 24 | #define HEX_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | size_t hexadecimalToBinary(char *input, size_t inputSize, char *output, size_t outputSize); 31 | size_t binaryToHexadecimal(char *input, size_t inputSize, char *output, size_t outputSize); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/hexdec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define HEXDEC_C 23 | 24 | #include "common.h" 25 | #include "hexdec_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "hexdec_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __hexdec_command = { .names = &commandNames, .ep = &hexdec_entry, .short_desc = &hexdec_shortdesc, .usage = &hexdec_usage }; 37 | EXPORTED commandEntry_t * hexdec_command = &__hexdec_command; 38 | 39 | // 'hexdec' function - decode hexadecimal presentation of data from STDIN to STDOUT 40 | 41 | int hexdec_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | char buffer[80]; 44 | size_t read = 0; 45 | 46 | if (argc > argo + 1) 47 | { 48 | int opt; 49 | int optIndex = 0; 50 | 51 | static struct option options_long[] = { 52 | verbosity_options_long, 53 | options_long_end, 54 | }; 55 | char * options_short = ":" verbosity_options_short; 56 | 57 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 58 | { 59 | switch (opt) 60 | { 61 | check_verbosity_options_short(); 62 | help_option(); 63 | getopt_invalid_option(); 64 | invalid_option(opt); 65 | } 66 | } 67 | if (optind < argc) 68 | warnAboutExtraArguments(argv, optind + 1); 69 | } 70 | 71 | if (isatty(0)) 72 | { 73 | errorMessage(errorNoReadFromTTY); 74 | return EXIT_FAILURE; 75 | } 76 | 77 | if (isAnyError()) 78 | return EXIT_FAILURE; 79 | 80 | resetError(); 81 | 82 | while ((read = fread(buffer, 1, sizeof(buffer), stdin)) > 0) 83 | { 84 | char withoutSpaces[sizeof(buffer)]; 85 | size_t used = 0; 86 | char * in; 87 | char * out; 88 | int i; 89 | size_t more = read; 90 | 91 | in = buffer; 92 | out = withoutSpaces; 93 | while (more > 0) 94 | { 95 | for (i = more; i > 0; i--, in++) 96 | { 97 | if (isspace(*(in))) 98 | continue; 99 | *(out++) = *in; 100 | used++; 101 | } 102 | if (used == sizeof(withoutSpaces)) 103 | break; 104 | more = fread(buffer, 1, sizeof(withoutSpaces) - used, stdin); 105 | if (more == 0) 106 | break; 107 | in = buffer; 108 | } 109 | read = hexadecimalToBinary(withoutSpaces, used, buffer, sizeof(buffer)); 110 | if (read == 0 || isAnyError()) 111 | break; 112 | 113 | if (fwrite(buffer, read, 1, stdout) != 1) 114 | { 115 | setError(WRITE_FAILED); 116 | break; 117 | } 118 | } 119 | 120 | if (isAnyError()) 121 | { 122 | if (isError(WRITE_FAILED)) 123 | { 124 | errorMessage(errorWriteFailed); 125 | } 126 | else if (isError(INV_HEX_DATA)) 127 | { 128 | errorMessage(errorInvalidHexValue); 129 | } 130 | else if (isError(INV_HEX_SIZE)) 131 | { 132 | errorMessage(errorInvalidHexSize); 133 | } 134 | else if (isError(INV_B64_ENC_SIZE)) 135 | { 136 | errorMessage(errorInvalidDataSize); 137 | } 138 | else 139 | { 140 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 141 | } 142 | } 143 | 144 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 145 | } 146 | 147 | #pragma GCC diagnostic pop 148 | -------------------------------------------------------------------------------- /src/hexdec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef HEXDEC_H 23 | 24 | #define HEXDEC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void hexdec_usage(const bool help, const bool version); 31 | int hexdec_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef HEXDEC_C 34 | 35 | extern commandEntry_t * hexdec_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/hexdec_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void hexdec_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program takes hexadecimal encoded data from STDIN and decodes it to binary.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntryVerbose(); 48 | addOptionsEntryQuiet(); 49 | addOptionsEntryStrict(); 50 | addOptionsEntryHelp(); 51 | addOptionsEntryVersion(); 52 | showOptionsEnd(out); 53 | 54 | fprintf(out, 55 | "\nThe decoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 56 | "aborted.\n" 57 | ); 58 | 59 | showUsageFinalize(out, help, version); 60 | } 61 | 62 | char * hexdec_shortdesc(void) 63 | { 64 | return "decode hexadecimal encoded data"; 65 | } 66 | -------------------------------------------------------------------------------- /src/hexenc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define HEXENC_C 23 | 24 | #include "common.h" 25 | #include "hexenc_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "hexenc_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __hexenc_command = { .names = &commandNames, .ep = &hexenc_entry, .usage = &hexenc_usage, .short_desc = &hexenc_shortdesc, .finalNewlineOnTTY = true }; 37 | EXPORTED commandEntry_t * hexenc_command = &__hexenc_command; 38 | 39 | // 'hexenc' function - encode binary data from STDIN to its hexadecimal presentation on STDOUT 40 | 41 | int hexenc_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | size_t charsOnLine = 0; 44 | char buffer[120]; 45 | size_t read = 0; 46 | 47 | if (argc > argo + 1) 48 | { 49 | int opt; 50 | int optIndex = 0; 51 | 52 | static struct option options_long[] = { 53 | width_options_long, 54 | verbosity_options_long, 55 | options_long_end, 56 | }; 57 | char * options_short = ":" width_options_short verbosity_options_short; 58 | 59 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 60 | { 61 | switch (opt) 62 | { 63 | check_width_options_short(); 64 | check_verbosity_options_short(); 65 | help_option(); 66 | getopt_invalid_option(); 67 | invalid_option(opt); 68 | } 69 | } 70 | if (optind < argc) 71 | warnAboutExtraArguments(argv, optind + 1); 72 | } 73 | 74 | if (isatty(0)) 75 | { 76 | errorMessage(errorNoReadFromTTY); 77 | return EXIT_FAILURE; 78 | } 79 | 80 | if (isAnyError()) 81 | return EXIT_FAILURE; 82 | 83 | resetError(); 84 | 85 | while ((read = fread(buffer, 1, sizeof(buffer), stdin)) > 0) 86 | { 87 | char output[(sizeof(buffer) * 2) + 2]; /* one more byte for optional end of string */ 88 | size_t outputSize = binaryToHexadecimal(buffer, read, output, sizeof(output) - 1); 89 | 90 | if (outputSize == 0) break; 91 | resetError(); 92 | 93 | size_t toWrite = outputSize; 94 | char * out = output; 95 | 96 | out = wrapOutput(stdout, &charsOnLine, &toWrite, out); 97 | if (isAnyError()) 98 | break; 99 | 100 | if ((toWrite > 0) && fwrite(out, toWrite, 1, stdout) != 1) 101 | { 102 | setError(WRITE_FAILED); 103 | break; 104 | } 105 | charsOnLine += toWrite; 106 | } 107 | if (!isAnyError()) 108 | wrapOutput(stdout, &charsOnLine, NULL, NULL); 109 | 110 | if (isAnyError()) 111 | { 112 | if (isError(WRITE_FAILED)) 113 | { 114 | errorMessage(errorWriteFailed); 115 | } 116 | else 117 | { 118 | errorMessage(errorUnexpectedError, getError(), getErrorText(getError())); 119 | } 120 | } 121 | 122 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 123 | } 124 | 125 | #pragma GCC diagnostic pop 126 | -------------------------------------------------------------------------------- /src/hexenc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef HEXENC_H 23 | 24 | #define HEXENC_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void hexenc_usage(const bool help, const bool version); 31 | int hexenc_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef HEXENC_C 34 | 35 | extern commandEntry_t * hexenc_command; 36 | 37 | #endif 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/hexenc_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void hexenc_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program converts binary data to hexadecimal strings.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-w, --wrap-lines [ " __undl("width") " ]", "enable line breaks (wrap lines) on output data and (opt.) define the maximum width of a line (instead of the default value " STRING(DECODER_CONFIG_WRAP_LINE_SIZE) ")", 8); 48 | addOptionsEntryVerbose(); 49 | addOptionsEntryQuiet(); 50 | addOptionsEntryStrict(); 51 | addOptionsEntryHelp(); 52 | addOptionsEntryVersion(); 53 | showOptionsEnd(out); 54 | 55 | fprintf(out, 56 | "\nThe encoded data is written to STDOUT. If STDIN is connected to a terminal device, execution will be\n" 57 | "aborted.\n" 58 | ); 59 | 60 | fprintf(out, 61 | "\nYou can force lines with limited width using the '--wrap-lines' (or '-w') option. Optionally you can\n" 62 | "set your wanted line width too.\n" 63 | ); 64 | 65 | showUsageFinalize(out, help, version); 66 | } 67 | 68 | char * hexenc_shortdesc(void) 69 | { 70 | return "encode data to their hexadecimal representation"; 71 | } 72 | -------------------------------------------------------------------------------- /src/license.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define LICENSE_C 23 | 24 | #include "common.h" 25 | 26 | // display license text 27 | 28 | static char * license = "\ 29 | Copyright (C) 2014-2020 P.Haemmerlein (peterpawn@yourfritz.de)\n\n\ 30 | This project is free software, you can redistribute it and/or modify it under the terms of the GNU\n\ 31 | General Public License as published by the Free Software Foundation; either version 2 of the\n\ 32 | License, or (at your option) any later version.\n\n\ 33 | This project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n\ 34 | even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 35 | See the GNU General Public License under http://www.gnu.org/licenses/gpl-2.0.html for more details.\n\ 36 | "; 37 | 38 | void showLicense(FILE * out) 39 | { 40 | fprintf(out, "%s", license); 41 | } 42 | -------------------------------------------------------------------------------- /src/license.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef LICENSE_H 23 | 24 | #define LICENSE_H 25 | 26 | void showLicense(FILE * out); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef MEMORY_H 23 | 24 | #define MEMORY_H 25 | 26 | #include "common.h" 27 | 28 | #define DEFAULT_MEMORY_BUFFER_SIZE DECODER_CONFIG_MEMORY_BUFFER_SIZE 29 | 30 | // memory structure for file buffering 31 | 32 | // STDIN to memory structures 33 | 34 | typedef struct memoryBuffer { 35 | struct memoryBuffer *next; 36 | struct memoryBuffer *prev; 37 | size_t size; 38 | size_t used; 39 | char data[]; 40 | } memoryBuffer_t; 41 | 42 | // function prototypes 43 | 44 | void memoryBufferSetSize(size_t size); 45 | 46 | memoryBuffer_t * memoryBufferNew(size_t size); 47 | memoryBuffer_t * memoryBufferFreeChain(memoryBuffer_t *start); 48 | memoryBuffer_t * memoryBufferConsolidateData(memoryBuffer_t *start); 49 | 50 | memoryBuffer_t * memoryBufferReadFile(FILE * file, size_t chunkSize); 51 | size_t memoryBufferDataSize(memoryBuffer_t *top); 52 | bool memoryBufferProcessFile(memoryBuffer_t * *buffer, size_t offset, char * key, FILE * out, char * filesKey); 53 | 54 | char * memoryBufferFindString(memoryBuffer_t * *buffer, size_t *offset, char *find, size_t findSize, bool *split); 55 | char * memoryBufferAdvancePointer(memoryBuffer_t * *buffer, size_t *lastOffset, size_t offset); 56 | char * memoryBufferSearchValueEnd(memoryBuffer_t * *buffer, size_t *offset, size_t * size, bool *split); 57 | 58 | void * clearMemory(void * buffer, size_t size, bool freeBuffer); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/nettle/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | 3 | prj := nettle-$(NETTLE_VERSION) 4 | 5 | .PHONY: build clean all nettle-headers nettle-lib 6 | 7 | all: $(DESTDIR)/libnettle.a nettle-headers 8 | 9 | $(prj): 10 | ./download.sh $(NETTLE_VERSION) 11 | 12 | $(prj)/config.status: | $(prj) 13 | cd $(prj); \ 14 | umask 077; \ 15 | ./configure --disable-shared --disable-public-key --disable-openssl --disable-documentation --enable-mini-gmp CFLAGS="-O2 -ffunction-sections -fdata-sections $(CFLAGS)" --prefix= $(NETTLE_CONFIGURE) 16 | 17 | clean: 18 | @for d in $$(find . -type d -name "nettle-*"); do [ -d $$d ] && ( cd $$d; make clean; cd ..; rm -r $$d 2>/dev/null ) || true; done; \ 19 | [ -f $(DESTDIR)/libnettle.a ] && rm $(DESTDIR)/libnettle.a 2>/dev/null; \ 20 | rm $(DESTDIR)/libnettle.so* 2>/dev/null && true; \ 21 | [ -d $(DESTDIR)/include/nettle ] && rm -r $(DESTDIR)/include/nettle 2>/dev/null; \ 22 | rm nisse.pub nettle*.tar.gz* 2>/dev/null; \ 23 | printf "Cleanup done.\n" 1>&2 24 | 25 | build: $(prj)/config.status 26 | $(MAKE) -C $(prj) SUBDIRS= 27 | 28 | nettle-shared: build 29 | $(MAKE) -C $(prj) DESTDIR="$(DESTDIR)" libdir="" install-shared-nettle 30 | 31 | nettle-static: build 32 | $(MAKE) -C $(prj) DESTDIR="$(DESTDIR)" libdir="" install-static 33 | 34 | nettle-headers: build 35 | $(MAKE) -C $(prj) DESTDIR="$(DESTDIR)" install-headers 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/options.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define OPTIONS_C 23 | 24 | #include "common.h" 25 | 26 | #pragma GCC diagnostic push 27 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 28 | #pragma GCC diagnostic ignored "-Wformat-security" 29 | 30 | EXPORTED bool setAlternativeEnvironment(char * newEnvironment) 31 | { 32 | struct stat st; 33 | 34 | if (stat(newEnvironment, &st)) 35 | { 36 | int error = errno; 37 | 38 | errorMessage(errorAccessingEnvironment, errno, strerror(error), newEnvironment); 39 | return false; 40 | } 41 | setEnvironmentPath(newEnvironment); 42 | 43 | return true; 44 | } 45 | 46 | EXPORTED bool checkLastArgumentIsInputFile(char * name) 47 | { 48 | struct stat st; 49 | 50 | if (stat(name, &st)) 51 | return false; 52 | 53 | verboseMessage(verboseRedirectStdin, name); 54 | /* 55 | It's possible to re-assign 'stdin' with glibc and others, but with 56 | C89/C99 'stdin' is a macro and for better portability, we use an own 57 | variable here. 58 | The old fd may be closed first (according to POSIX), as a result the 59 | stream behind the pointer may be invalid, if an error occurs. 60 | */ 61 | FILE * stdin_reloc = freopen(name, "r", stdin); 62 | if (!stdin_reloc) 63 | { 64 | errorMessage(errorUnexpectedIOError, errno, "freopen", "STDIN"); 65 | setError(IO_ERROR); 66 | } 67 | 68 | return (stdin_reloc ? true : false); 69 | } 70 | 71 | EXPORTED void warnAboutExtraArguments(char ** argv, int i) 72 | { 73 | int index = i; 74 | 75 | while (argv[index]) 76 | { 77 | warningMessage(verboseTooMuchArguments, argv[index]); 78 | if (isStrict()) 79 | setError(WARNING_ISSUED); 80 | index++; 81 | } 82 | } 83 | 84 | static char optionString[16]; 85 | 86 | EXPORTED char * optionsString(int option, const char * longOption) 87 | { 88 | if (longOption) 89 | snprintf(optionString, sizeof(optionString), "--%s", longOption); 90 | else 91 | snprintf(optionString, sizeof(optionString), "-%c", option); 92 | return optionString; 93 | } 94 | 95 | EXPORTED int setLineWidth(char * value, char * option, char * next) 96 | { 97 | char * val = value; 98 | int offset = 0; 99 | 100 | setLineWrap(); 101 | if (!value) 102 | { 103 | if (next && *next && *next != '-' && *next >= '0' && *next <= '9') 104 | { 105 | val = next; 106 | offset = 1; 107 | } 108 | } 109 | 110 | if (val && *val) 111 | { 112 | char * endString = NULL; 113 | char * startString = val; 114 | unsigned long lineSize = strtoul(startString, &endString, 10); 115 | 116 | if (*startString && strlen(endString)) 117 | { 118 | errorMessage(errorInvalidWidth, startString, option); 119 | return -1; 120 | } 121 | setOutputLineWidth(lineSize); 122 | } 123 | 124 | return offset; 125 | } 126 | 127 | EXPORTED bool setInputBufferSize(char * value, UNUSED char * option) 128 | { 129 | char * val = value; 130 | 131 | if (val && *val) 132 | { 133 | char * endString = NULL; 134 | char * startString = val; 135 | size_t size = strtoul(startString, &endString, 10); 136 | 137 | if (*startString && strlen(endString)) 138 | { 139 | if ((strcmp(endString, "k") == 0) || (strcmp(endString, "K") == 0)) 140 | { 141 | size *= 1024; 142 | } 143 | else if ((strcmp(endString, "m") == 0) || (strcmp(endString, "M") == 0)) 144 | { 145 | size *= 1024 * 1024; 146 | } 147 | else 148 | { 149 | errorMessage(errorInvalidBufferSize, startString); 150 | return false; 151 | } 152 | } 153 | if ((size < 32) || (size > (16 * 1024 * 1024))) 154 | { 155 | errorMessage(errorInvalidBufferSize, startString); 156 | return false; 157 | } 158 | memoryBufferSetSize(size); 159 | verboseMessage(verboseBufferSize, size); 160 | } 161 | 162 | return true; 163 | } 164 | 165 | #pragma GCC diagnostic pop 166 | -------------------------------------------------------------------------------- /src/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef OPTIONS_H 23 | 24 | #define OPTIONS_H 25 | 26 | // helper macros 27 | 28 | #define __usage(help, version) ((*entry->usage)(help, version)) 29 | 30 | #ifdef DECODER_CONFIG_AUTO_USAGE 31 | #define __autoUsage() __usage(false, false) 32 | #else 33 | #define __autoUsage() 34 | #endif 35 | 36 | #define isStrict() (__getVerbosity() == VERBOSITY_STRICT) 37 | 38 | #define failOnStrict() if (isStrict())\ 39 | return EXIT_FAILURE 40 | 41 | #define verbosity_options_long { "verbose", no_argument, NULL, 'v' },\ 42 | { "quiet", no_argument, NULL, 'q' },\ 43 | { "strict", no_argument, NULL, 's' },\ 44 | { "help", no_argument, NULL, 'h' },\ 45 | { "version", no_argument, NULL, 'V' } 46 | 47 | #define options_long_end { NULL, 0, NULL, 0 } 48 | 49 | #define verbosity_options_short "vqshV" 50 | 51 | #define check_verbosity_options_short() case 'v':\ 52 | __setVerbosity(VERBOSITY_VERBOSE);\ 53 | break;\ 54 | case 'q':\ 55 | __setVerbosity(VERBOSITY_SILENT);\ 56 | break;\ 57 | case 's':\ 58 | __setVerbosity(VERBOSITY_STRICT);\ 59 | break 60 | 61 | #define help_option() case 'h':\ 62 | __usage(true, false);\ 63 | return EXIT_SUCCESS;\ 64 | case 'V':\ 65 | __usage(false, true);\ 66 | return EXIT_SUCCESS;\ 67 | 68 | #define getopt_invalid_option() case '?':\ 69 | case 0:\ 70 | errorMessage((*((argv[optind]) + 1) == '-' ? errorInvalidOrAmbiguousOption : errorInvalidOption), argv[optind]);\ 71 | __autoUsage();\ 72 | return EXIT_FAILURE 73 | 74 | #define getopt_argument_missing() case ':':\ 75 | errorMessage(errorMissingOptionValue, argv[optind]);\ 76 | __autoUsage();\ 77 | return EXIT_FAILURE 78 | 79 | // options check default 80 | 81 | #define invalid_option(opt) default:\ 82 | errorMessage(errorInvalidOption, argv[optind]);\ 83 | __autoUsage();\ 84 | return EXIT_FAILURE 85 | 86 | // options for more than one applet 87 | 88 | // alternate environment file 89 | 90 | #define altenv_options_long { "alt-env", required_argument, NULL, 'a' } 91 | 92 | #define altenv_options_short "a:" 93 | 94 | #define check_altenv_options_short() case 'a':\ 95 | if ((altEnv = setAlternativeEnvironment(optarg)) == false) {\ 96 | __autoUsage();\ 97 | return EXIT_FAILURE;\ 98 | }\ 99 | break 100 | 101 | #define altenv_verbose_message() if (altEnv)\ 102 | verboseMessage(verboseAltEnv, getEnvironmentPath()) 103 | 104 | // wrap output lines 105 | 106 | #define width_options_long { "wrap-lines", optional_argument, NULL, 'w' } 107 | 108 | #define width_options_short "w::" 109 | 110 | #define check_width_options_short() case 'w':\ 111 | {\ 112 | int offset = setLineWidth(optarg, argv[optind], argv[optind + 1]);\ 113 | if (offset == -1) {\ 114 | __autoUsage();\ 115 | return EXIT_FAILURE;\ 116 | }\ 117 | else optind += offset;\ 118 | }\ 119 | break 120 | 121 | // function prototypes 122 | 123 | bool setAlternativeEnvironment(char * newEnvironment); 124 | int setLineWidth(char * value, char * option, char * next); 125 | bool setInputBufferSize(char * value, char * option); 126 | bool checkLastArgumentIsInputFile(char * name); 127 | void warnAboutExtraArguments(char ** argv, int i); 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /src/output.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef OUTPUT_H 23 | 24 | #define OUTPUT_H 25 | 26 | // verbosity level definitions 27 | 28 | typedef enum { 29 | VERBOSITY_SILENT, /* no error messages on STDERR */ 30 | VERBOSITY_NORMAL, /* show only error messages on STDERR */ 31 | VERBOSITY_STRICT, /* fail on warnings shown on STDERR */ 32 | VERBOSITY_VERBOSE /* show extra information on STDERR */ 33 | } decoder_verbosity_t; 34 | 35 | #ifndef OUTPUT_C 36 | 37 | // global verbosity setting 38 | 39 | extern decoder_verbosity_t * __decoder_verbosity; 40 | 41 | extern char * verboseFoundProperty; 42 | extern char * verboseMissingProperty; 43 | extern char * verboseAltEnv; 44 | extern char * verboseUsingKey; 45 | extern char * verbosePasswordHash; 46 | extern char * verboseSerialUsed; 47 | extern char * verboseMACUsed; 48 | extern char * verboseWLANKeyUsed; 49 | extern char * verboseTR069PPUsed; 50 | extern char * verboseDeviceKeyHash; 51 | extern char * verbosePasswordUsed; 52 | extern char * verboseRedirectStdin; 53 | extern char * verboseTooMuchArguments; 54 | extern char * verboseDecryptionFailed; 55 | extern char * verboseFoundCipherText; 56 | extern char * verboseDecryptedTo; 57 | extern char * verboseDecryptedToHex; 58 | extern char * verboseDecryptFailed; 59 | extern char * verboseDisplayFailed; 60 | extern char * verboseWrongSerialLength; 61 | extern char * verboseWrongMACAddress; 62 | extern char * verboseWrongWLANKey; 63 | extern char * verboseWrongTR069Passphrase; 64 | extern char * verboseAltEnvIgnored; 65 | extern char * verboseWrapLinesIgnored; 66 | extern char * verboseBufferSize; 67 | extern char * verboseInputDataConsolidated; 68 | extern char * verboseNoConsolidate; 69 | extern char * verboseChecksumFound; 70 | extern char * verboseChecksumIsValid; 71 | extern char * verboseNewChecksum; 72 | extern char * verboseOpenedOutputFile; 73 | 74 | extern char * verboseDebugKey; 75 | extern char * verboseDebugBase32; 76 | extern char * verboseDebugInput; 77 | extern char * verboseDebugIV; 78 | extern char * verboseDebugEncData; 79 | extern char * verboseDebugDecData; 80 | extern char * verboseDebugSize; 81 | extern char * verboseDebugIsString; 82 | extern char * verboseDebugValue; 83 | 84 | #endif 85 | 86 | // default values 87 | 88 | #define DEFAULT_OUTPUT_LINE_WIDTH DECODER_CONFIG_WRAP_LINE_SIZE 89 | 90 | // helper macros 91 | 92 | #define colAppletName(color,bell) ( fprintf(stderr, "\033[1m\033[3" #color "m%s\033[0m: %s", getAppletName(), (bell ? "\a" : "")) ) 93 | 94 | #define isVerbose() (__getVerbosity() == VERBOSITY_VERBOSE) 95 | 96 | #define errorMessage(...) if (__getVerbosity() != VERBOSITY_SILENT) {\ 97 | colAppletName(1,1);\ 98 | fprintf(stderr, ##__VA_ARGS__);\ 99 | } 100 | 101 | #define warningMessage(...) if (__getVerbosity() != VERBOSITY_SILENT) {\ 102 | colAppletName(3,0);\ 103 | fprintf(stderr, ##__VA_ARGS__ );\ 104 | } 105 | 106 | #define warningMessageNoApplet(...) if (__getVerbosity() != VERBOSITY_SILENT) {\ 107 | fprintf(stderr, ##__VA_ARGS__ );\ 108 | } 109 | 110 | #define verboseMessage(...) if (__getVerbosity() == VERBOSITY_VERBOSE) {\ 111 | colAppletName(4,0);\ 112 | fprintf(stderr, ##__VA_ARGS__ );\ 113 | } 114 | 115 | #define verboseMessageNoApplet(...) if (__getVerbosity() == VERBOSITY_VERBOSE) {\ 116 | fprintf(stderr, ##__VA_ARGS__ );\ 117 | } 118 | 119 | // function prototypes 120 | 121 | char * wrapOutput(FILE * outFile, size_t *charsOnLine, size_t *toWrite, char *output); 122 | char * optionsString(int option, const char * longOption); 123 | decoder_verbosity_t __getVerbosity(void); 124 | void __setVerbosity(decoder_verbosity_t verbosity); 125 | size_t getOutputLineWidth(void); 126 | void setOutputLineWidth(size_t width); 127 | void setLineWrap(void); 128 | bool getLineWrap(void); 129 | void setAppletName(char * name); 130 | char * getAppletName(void); 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /src/pkpwd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define PKPWD_C 23 | 24 | #include "common.h" 25 | #include "pkpwd_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "pkpwd_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __pkpwd_command = { .names = &commandNames, .ep = &pkpwd_entry, .usage = &pkpwd_usage, .short_desc = &pkpwd_shortdesc, .usesCrypto = true, .finalNewlineOnTTY = true }; 37 | EXPORTED commandEntry_t * pkpwd_command = &__pkpwd_command; 38 | 39 | // 'privatekeypassword' function - compute the secret key for the private key file websrv_ssl_key.pem 40 | 41 | int pkpwd_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | char out[8 + 1]; 44 | size_t outLen = sizeof(out); 45 | bool altEnv = false; 46 | char * maca = NULL; 47 | 48 | if (argc > argo + 1) 49 | { 50 | int opt; 51 | int optIndex = 0; 52 | 53 | static struct option options_long[] = { 54 | verbosity_options_long, 55 | altenv_options_long, 56 | options_long_end, 57 | }; 58 | char * options_short = ":" altenv_options_short verbosity_options_short; 59 | 60 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 61 | { 62 | switch (opt) 63 | { 64 | check_altenv_options_short(); 65 | check_verbosity_options_short(); 66 | help_option(); 67 | getopt_invalid_option(); 68 | invalid_option(opt); 69 | } 70 | } 71 | if (optind < (argc - argo)) 72 | { 73 | maca = argv[optind + argo]; 74 | warnAboutExtraArguments(argv, optind + argo + 1); 75 | } 76 | } 77 | 78 | if (maca) 79 | { 80 | if (!checkMACAddress(maca)) 81 | { 82 | errorMessage(errorWrongMACAddress, maca); 83 | setError(INV_HEX_DATA); 84 | } 85 | 86 | if (!isAnyError() && altEnv) 87 | { 88 | warningMessage(verboseAltEnvIgnored); 89 | failOnStrict(); 90 | } 91 | } 92 | else 93 | { 94 | altenv_verbose_message(); 95 | 96 | maca = getEnvironmentValue(NULL, URLADER_MACA_NAME); 97 | if (!maca) 98 | { 99 | errorMessage(errorMissingDeviceProperty, URLADER_MACA_NAME); 100 | } 101 | } 102 | 103 | if (isAnyError()) 104 | return EXIT_FAILURE; 105 | 106 | resetError(); 107 | 108 | verboseMessage(verboseMACUsed, maca); 109 | 110 | if (privateKeyPassword(out, &outLen, maca)) 111 | { 112 | if (fwrite(out, outLen, 1, stdout) != 1) 113 | { 114 | setError(WRITE_FAILED); 115 | errorMessage(errorWriteFailed); 116 | } 117 | } 118 | 119 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 120 | } 121 | 122 | #pragma GCC diagnostic pop 123 | -------------------------------------------------------------------------------- /src/pkpwd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef PKPWD_H 23 | 24 | #define PKPWD_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void pkpwd_usage(const bool help, const bool version); 31 | int pkpwd_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef PKPWD_C 34 | 35 | extern commandEntry_t * pkpwd_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/pkpwd_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void pkpwd_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program computes the secret key used to encrypt the file '/var/flash/websrv_ssl_key.pem',\n" 39 | "which contains the private key for the X.509 certificate used to provide the GUI over a TLS-secured\n" 40 | "connection.\n" 41 | ); 42 | 43 | showFormatHeader(out); 44 | addSpace(); 45 | addOption("options"); 46 | addSpace(); 47 | endOptions(); 48 | addSpace(); 49 | addOption(URLADER_MACA_NAME); 50 | showFormatEnd(out); 51 | 52 | showOptionsHeader("options"); 53 | addOptionsEntry("-a, --alt-env " __undl("filename"), "use an alternative source for the 'urlader environment'", 8); 54 | addOptionsEntryVerbose(); 55 | addOptionsEntryQuiet(); 56 | addOptionsEntryStrict(); 57 | addOptionsEntryHelp(); 58 | addOptionsEntryVersion(); 59 | showOptionsEnd(out); 60 | 61 | fprintf(out, 62 | "\nThe program reads the device property %s from the procfs on a FRITZ!OS device (or from an\n" 63 | "alternative source) and computes the secret key, which protects the private key file for the GUI\n" 64 | "certificate against simple read-outs and later abuse.\n", 65 | showUndl(URLADER_MACA_NAME) 66 | ); 67 | 68 | fprintf(out, 69 | "\nIf you want to get the password for another device, you can specify - at your option - the %s\n" 70 | "value as argument and no 'urlader environment' will be used.\n", 71 | showUndl(URLADER_MACA_NAME) 72 | ); 73 | 74 | fprintf(out, 75 | "\nThe 'urlader environment' is usually available with a fixed path name on procfs, but if the\n" 76 | "program is used outside of FRITZ!OS, an alternative path may be specified with the '--alt-env'\n" 77 | "(or '-a') option. This option is only useful, if you do not already specify the value to use as\n" 78 | "last argument on the command line." 79 | ); 80 | 81 | showUsageFinalize(out, help, version); 82 | } 83 | 84 | char * pkpwd_shortdesc(void) 85 | { 86 | return "compute the secret key used to encrypt the private key for the box certificate (which is used for the GUI)"; 87 | } 88 | -------------------------------------------------------------------------------- /src/pwfrdev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define PWFRDEV_C 23 | 24 | #include "common.h" 25 | #include "pwfrdev_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "pwfrdev_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __pwfrdev_command = { .names = &commandNames, .ep = &pwfrdev_entry, .usage = &pwfrdev_usage, .short_desc = &pwfrdev_shortdesc, .usesCrypto = true }; 37 | EXPORTED commandEntry_t * pwfrdev_command = &__pwfrdev_command; 38 | 39 | // 'password_from_device' function - compute the password hash from the current device properties 40 | 41 | int pwfrdev_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | bool hexOutput = false; 44 | bool forExport = false; 45 | char hash[MAX_DIGEST_SIZE]; 46 | size_t hashLen = sizeof(hash); 47 | char hex[(sizeof(hash) * 2) + 1]; 48 | size_t hexLen = 0; 49 | char * out; 50 | size_t outLen; 51 | bool altEnv = false; 52 | 53 | if (argc > argo + 1) 54 | { 55 | int opt; 56 | int optIndex = 0; 57 | 58 | static struct option options_long[] = { 59 | verbosity_options_long, 60 | altenv_options_long, 61 | { "hex-output", no_argument, NULL, 'x' }, 62 | { "for-export", no_argument, NULL, 'e' }, 63 | options_long_end, 64 | }; 65 | char * options_short = ":" "xe" altenv_options_short verbosity_options_short; 66 | 67 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 68 | { 69 | switch (opt) 70 | { 71 | case 'x': 72 | hexOutput = true; 73 | break; 74 | 75 | case 'e': 76 | forExport = true; 77 | break; 78 | 79 | check_altenv_options_short(); 80 | check_verbosity_options_short(); 81 | help_option(); 82 | getopt_argument_missing(); 83 | getopt_invalid_option(); 84 | invalid_option(opt); 85 | } 86 | } 87 | if (optind < (argc - argo)) 88 | { 89 | warnAboutExtraArguments(argv, optind + argo); 90 | } 91 | } 92 | 93 | if (isAnyError()) 94 | return EXIT_FAILURE; 95 | 96 | resetError(); 97 | 98 | altenv_verbose_message(); 99 | 100 | keyFromDevice(hash, &hashLen, forExport); 101 | 102 | if (!isAnyError()) 103 | { 104 | hexLen = binaryToHexadecimal((char *) hash, hashLen, hex, sizeof(hex)); 105 | hex[hexLen] = 0; 106 | verboseMessage(verboseDeviceKeyHash, hex); 107 | } 108 | 109 | if (!isAnyError() && !hexOutput && isatty(1)) 110 | { 111 | if (fwrite("0x", 2, 1, stdout) != 1) 112 | { 113 | setError(WRITE_FAILED); 114 | errorMessage(errorWriteFailed); 115 | } 116 | hexOutput = true; 117 | } 118 | 119 | if (!isAnyError()) 120 | { 121 | if (hexOutput) 122 | { 123 | outLen = binaryToHexadecimal((char *) hash, hashLen, hex, sizeof(hex)); 124 | out = hex; 125 | entry->finalNewlineOnTTY = true; 126 | } 127 | else 128 | { 129 | outLen = hashLen; 130 | out = (char *) hash; 131 | } 132 | if (fwrite(out, outLen, 1, stdout) != 1) 133 | { 134 | setError(WRITE_FAILED); 135 | errorMessage(errorWriteFailed); 136 | } 137 | } 138 | 139 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 140 | } 141 | 142 | #pragma GCC diagnostic pop 143 | -------------------------------------------------------------------------------- /src/pwfrdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef PWFRDEV_H 23 | 24 | #define PWFRDEV_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void pwfrdev_usage(const bool help, const bool version); 31 | int pwfrdev_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef PWFRDEV_C 34 | 35 | extern commandEntry_t * pwfrdev_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/pwfrdev_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void pwfrdev_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program computes the device-specific key used to encrypt values stored in TFFS files.\n" 39 | ); 40 | 41 | showFormatHeader(out); 42 | addSpace(); 43 | addOption("options"); 44 | showFormatEnd(out); 45 | 46 | showOptionsHeader("options"); 47 | addOptionsEntry("-a, --alt-env " __undl("filename"), "use an alternative source for the 'urlader environment'", 8); 48 | addOptionsEntry("-e, --for-export", "create a key usable for a settings export file", 0); 49 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 50 | addOptionsEntryVerbose(); 51 | addOptionsEntryQuiet(); 52 | addOptionsEntryStrict(); 53 | addOptionsEntryHelp(); 54 | addOptionsEntryVersion(); 55 | showOptionsEnd(out); 56 | 57 | fprintf(out, 58 | "\nThe program reads the device properties %s, %s and %s from the procfs on a\n" 59 | "FRITZ!OS device (or from an alternative source) and computes the key used to encrypt security-\n" 60 | "related settings in TFFS files. If the device in question has a configured CWMP account (for TR-069\n" 61 | "communications), the property %s is added to this key.\n", 62 | showUndl(URLADER_SERIAL_NAME), showUndl(URLADER_MACA_NAME), showUndl(URLADER_WLANKEY_NAME), showUndl(URLADER_TR069PP_NAME) 63 | ); 64 | 65 | fprintf(out, 66 | "\nThe 'urlader environment' is usually available with a fixed path name on procfs, but while a\n" 67 | "FRITZ!OS device is started, a copy will be created in '/var/env'. If the program is used outside of\n" 68 | "FRITZ!OS (or it's supposed to use properties from another device), an alternative %s may be\n" 69 | "set and used with the '--alt-env' (or '-a') option. The original file format (name and value\n" 70 | "delimited by a single TAB character, no empty lines in the file) must be respected.\n", 71 | showUndl("filename") 72 | ); 73 | 74 | fprintf(out, 75 | "\nThe key used to encrypt export files, if they're created without an user-defined password, differs\n" 76 | "from the key for internal storage. If you need an export key for a device, you may specify the\n" 77 | "option '--for-export' (or '-e') to create such one.\n" 78 | ); 79 | 80 | fprintf(out, 81 | "\nThe computed key will be written to STDOUT; if the option '--hex-output' (or '-x') was specified,\n" 82 | "output data will be converted to a hexadecimal string. If STDOUT is connected to a terminal device,\n" 83 | "hexadecimal output is activated automatically. As long as the option for hexadecimal output wasn't\n" 84 | "selected explicitely, the value will get a prefix '0x' in front of it.\n" 85 | ); 86 | 87 | showUsageFinalize(out, help, version); 88 | } 89 | 90 | char * pwfrdev_shortdesc(void) 91 | { 92 | return "compute a secret key based on properties of the current device"; 93 | } 94 | -------------------------------------------------------------------------------- /src/userpw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #define USERPW_C 23 | 24 | #include "common.h" 25 | #include "userpw_usage.c" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wformat-nonliteral" 29 | #pragma GCC diagnostic ignored "-Wformat-security" 30 | 31 | static char * __commandNames[] = { 32 | #include "userpw_commands.c" 33 | NULL 34 | }; 35 | static char * * commandNames = &__commandNames[0]; 36 | static commandEntry_t __userpw_command = { .names = &commandNames, .ep = &userpw_entry, .usage = &userpw_usage, .short_desc = &userpw_shortdesc, .usesCrypto = true }; 37 | EXPORTED commandEntry_t * userpw_command = &__userpw_command; 38 | 39 | // 'user_password' function - compute the password hash for export files with a user-specified password 40 | 41 | int userpw_entry(int argc, char** argv, int argo, commandEntry_t * entry) 42 | { 43 | bool hexOutput = false; 44 | char * password = NULL; 45 | char hash[MAX_DIGEST_SIZE]; 46 | size_t hashLen = sizeof(hash); 47 | char hex[(sizeof(hash) * 2) + 1]; 48 | size_t hexLen = 0; 49 | char * out; 50 | size_t outLen; 51 | 52 | if (argc > argo + 1) 53 | { 54 | int opt; 55 | int optIndex = 0; 56 | 57 | static struct option options_long[] = { 58 | verbosity_options_long, 59 | { "hex-output", no_argument, NULL, 'x' }, 60 | options_long_end, 61 | }; 62 | char * options_short = ":" "x" verbosity_options_short; 63 | 64 | while ((opt = getopt_long(argc - argo, &argv[argo], options_short, options_long, &optIndex)) != -1) 65 | { 66 | switch (opt) 67 | { 68 | case 'x': 69 | hexOutput = true; 70 | break; 71 | 72 | check_verbosity_options_short(); 73 | help_option(); 74 | getopt_invalid_option(); 75 | invalid_option(opt); 76 | } 77 | } 78 | if (optind >= (argc - argo)) 79 | { 80 | errorMessage(errorPasswordMissing); 81 | __autoUsage(); 82 | return EXIT_FAILURE; 83 | } 84 | else 85 | { 86 | password = argv[optind + argo]; 87 | verboseMessage(verbosePasswordUsed, password); 88 | warnAboutExtraArguments(argv, optind + argo + 1); 89 | } 90 | } 91 | else 92 | { 93 | errorMessage(errorPasswordMissing); 94 | __autoUsage(); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | if (isAnyError()) 99 | return EXIT_FAILURE; 100 | 101 | resetError(); 102 | 103 | if ((hashLen = Digest(password, strlen(password), hash, hashLen)) == 0) 104 | { 105 | errorMessage(errorDigestComputation); 106 | return EXIT_FAILURE; 107 | } 108 | 109 | hexLen = binaryToHexadecimal((char *) hash, hashLen, hex, sizeof(hex)); 110 | hex[hexLen] = 0; 111 | verboseMessage(verbosePasswordHash, hex); 112 | if (!hexOutput && isatty(1)) 113 | { 114 | if (fwrite("0x", 2, 1, stdout) != 1) 115 | { 116 | setError(WRITE_FAILED); 117 | errorMessage(errorWriteFailed); 118 | } 119 | hexOutput = true; 120 | } 121 | if (hexOutput) 122 | { 123 | outLen = hexLen; 124 | out = hex; 125 | entry->finalNewlineOnTTY = true; 126 | } 127 | else 128 | { 129 | outLen = hashLen; 130 | out = (char *) hash; 131 | } 132 | if (fwrite(out, outLen, 1, stdout) != 1) 133 | { 134 | setError(WRITE_FAILED); 135 | errorMessage(errorWriteFailed); 136 | } 137 | 138 | return (!isAnyError() ? EXIT_SUCCESS : EXIT_FAILURE); 139 | } 140 | 141 | #pragma GCC diagnostic pop 142 | -------------------------------------------------------------------------------- /src/userpw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | #ifndef USERPW_H 23 | 24 | #define USERPW_H 25 | 26 | #include "common.h" 27 | 28 | // function prototypes 29 | 30 | void userpw_usage(const bool help, const bool version); 31 | int userpw_entry(int argc, char** argv, int argo, commandEntry_t * entry); 32 | 33 | #ifndef USERPW_C 34 | 35 | extern commandEntry_t * userpw_command; 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/userpw_usage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-2.0-or-later 3 | * 4 | * vim: set tabstop=4 syntax=c : 5 | * 6 | * Copyright (C) 2014-2020, Peter Haemmerlein (peterpawn@yourfritz.de) 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 2 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program, please look for the file LICENSE. 20 | */ 21 | 22 | // display usage help 23 | 24 | void userpw_usage(const bool help, UNUSED const bool version) 25 | { 26 | FILE * out = (help || version ? stdout : stderr); 27 | 28 | showUsageHeader(out, help, version); 29 | 30 | if (version) 31 | { 32 | fprintf(out, "\n"); 33 | return; 34 | } 35 | 36 | showPurposeHeader(out); 37 | fprintf(out, 38 | "This program generates a key, based on the specified password. The key may be used for the first\n" 39 | "stage of decryption for an export file or for decryption of a single value (with another program\n" 40 | "named %s).\n", 41 | showBold(DECODER_CONFIG_DECRYPT_SINGLE_VALUES_NAME) 42 | ); 43 | 44 | showFormatHeader(out); 45 | addSpace(); 46 | addOption("options"); 47 | addSpace(); 48 | endOptions(); 49 | addSpace(); 50 | addArgument("password"); 51 | showFormatEnd(out); 52 | 53 | showOptionsHeader("options"); 54 | addOptionsEntry("-x, --hex-output", "output data as a hexadecimal string", 0); 55 | addOptionsEntryVerbose(); 56 | addOptionsEntryQuiet(); 57 | addOptionsEntryStrict(); 58 | addOptionsEntryHelp(); 59 | addOptionsEntryVersion(); 60 | showOptionsEnd(out); 61 | 62 | fprintf(out, 63 | "\nAn export file has to be created with a user-specified password or the decryption will fail, 'cause\n" 64 | "the device's secret key - computed from only two device properties - was used to encrypt the key\n" 65 | "for the second stage.\n\n" 66 | "The generated key will be written to STDOUT; if the option '--hex-output' (or '-x') was specified,\n" 67 | "output data will be converted to a hexadecimal string. If STDOUT is connected to a terminal device,\n" 68 | "hexadecimal output is activated automatically. As long as the option for hexadecimal output wasn't\n" 69 | "selected explicitely, the value will get a prefix '0x' in front of it.\n\n" 70 | "If %s starts with a hyphen, you have to insert '--' in front of it.\n", 71 | showUndl("password") 72 | ); 73 | 74 | showUsageFinalize(out, help, version); 75 | } 76 | 77 | char * userpw_shortdesc(void) 78 | { 79 | return "compute a secret key based on an user password"; 80 | } 81 | --------------------------------------------------------------------------------