├── .clang-format ├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ ├── cifuzz.yml │ ├── clang-format.yml │ └── release.yml ├── .gitignore ├── AUTHORS ├── COPYING ├── COPYING.iOS ├── ChangeLog ├── Makefile.am ├── NEWS ├── README.md ├── THANKS ├── autogen.sh ├── build-package.sh ├── build-source-package.sh ├── conf ├── Makefile.am ├── bash-completion │ └── completions │ │ └── mosh └── ufw │ └── applications.d │ └── mosh ├── configure.ac ├── debian ├── changelog ├── control ├── copyright ├── docs ├── mosh.maintscript ├── rules ├── source │ └── format └── watch ├── fedora └── mosh.spec ├── m4 ├── ax_ac_append_to_file.m4 ├── ax_ac_print_to_file.m4 ├── ax_add_am_macro_static.m4 ├── ax_am_macros_static.m4 ├── ax_check_compile_flag.m4 ├── ax_check_gnu_make.m4 ├── ax_check_library.m4 ├── ax_check_link_flag.m4 ├── ax_code_coverage.m4 ├── ax_cxx_compile_stdcxx.m4 ├── ax_file_escapes.m4 ├── ax_require_defined.m4 ├── ax_with_curses.m4 └── pkg.m4 ├── macosx ├── .gitignore ├── Distribution.in ├── brew-deps.sh ├── build.sh ├── copying.rtf ├── gtar ├── mosh-package.pmdoc.in │ ├── 01prefix-contents.xml │ ├── 01prefix.xml │ └── index.xml ├── osx-xcode.sh ├── port-deps.sh └── readme.rtf ├── man ├── Makefile.am ├── mosh-client.1 ├── mosh-server.1 └── mosh.1 ├── ocb-license.html ├── scripts ├── Makefile.am ├── mosh.pl └── wrap-compiler-for-flag-check └── src ├── Makefile.am ├── crypto ├── Makefile.am ├── ae.h ├── base64.cc ├── base64.h ├── byteorder.h ├── crypto.cc ├── crypto.h ├── ocb_internal.cc ├── ocb_openssl.cc └── prng.h ├── examples ├── .gitignore ├── Makefile.am ├── benchmark.cc ├── decrypt.cc ├── encrypt.cc ├── ntester.cc ├── parse.cc └── termemu.cc ├── frontend ├── .gitignore ├── Makefile.am ├── mosh-client.cc ├── mosh-server.cc ├── stmclient.cc ├── stmclient.h ├── terminaloverlay.cc └── terminaloverlay.h ├── fuzz ├── Makefile.am ├── terminal_corpus │ ├── 3769c52698d426976ee402b9dbc3c2a7bd5e5485 │ ├── 3a52ce780950d4d969792a2559cd519d7ee8c727 │ ├── 3facad9d449f8b10a2d18ef821325639214afc3c │ ├── 433f367f36f48f78570c2013fef7a4f4b52b7c0c │ ├── 5ba93c9db0cff93f52b521d7420e43f6eda2784f │ ├── 64b6cc492319c39d017963ee8f5863520eb7b6b9 │ ├── 7c4d33785daa5c2370201ffa236b427aa37c9996 │ ├── 7fff5c5bdfcaecbe749a7eda1f831a4b0ac6c285 │ ├── 94fc46a4dd7043c8a22bc85f24aafdf0bc963125 │ ├── 9a78211436f6d425ec38f5c4e02270801f3524f8 │ ├── a70a7fcfa8e88039504b6a798314285419f51e16 │ ├── adc83b19e793491b1c6ea0fd8b46cd9f32e592fc │ ├── bf72240ede73688a77e62c38b4a112f15cb61802 │ ├── c822a8bc8c7d9f938990c2bfd0b24fd9d48af917 │ ├── e0d3c08cb28736844512c52dc05fa4e4efd91490 │ └── f195c020a28dfc5f2fb6af256b524ddcd93756ed ├── terminal_fuzzer.cc ├── terminal_parser_corpus │ ├── 7164cb6ab7e834fa6145bcf283e94b981313980d │ ├── 71853c6197a6a7f222db0f1978c7cb232b87c5ee │ ├── 7b98b1bb85d1afb4f154cfbe9c3d4791024a86b7 │ ├── 8a92b4d6e188b3e2fa7add9e123b702ed11f3695 │ ├── 99feeb7f36e52ff59d86c975a8e5ad1a2ab4629e │ ├── 9d5e4e241c99c93786eeddcd93c5ec23dd563881 │ ├── 9e016e2a52e879c9c6482303eea8eb7d92b4dd38 │ ├── a09fd95888cb80e1dcea4cc9dbd7d76928909927 │ ├── abb6d63b8f739c45c3c44f1772b88338e9b5e7a3 │ ├── adc83b19e793491b1c6ea0fd8b46cd9f32e592fc │ └── b67f23988e8274fcf6150a18dacb5ab3db49520d └── terminal_parser_fuzzer.cc ├── include └── Makefile.am ├── network ├── Makefile.am ├── compressor.cc ├── compressor.h ├── network.cc ├── network.h ├── networktransport-impl.h ├── networktransport.h ├── transportfragment.cc ├── transportfragment.h ├── transportsender-impl.h ├── transportsender.h └── transportstate.h ├── protobufs ├── Makefile.am ├── hostinput.proto ├── transportinstruction.proto └── userinput.proto ├── statesync ├── Makefile.am ├── completeterminal.cc ├── completeterminal.h ├── user.cc └── user.h ├── terminal ├── Makefile.am ├── parser.cc ├── parser.h ├── parseraction.cc ├── parseraction.h ├── parserstate.cc ├── parserstate.h ├── parserstatefamily.h ├── parsertransition.h ├── terminal.cc ├── terminal.h ├── terminaldispatcher.cc ├── terminaldispatcher.h ├── terminaldisplay.cc ├── terminaldisplay.h ├── terminaldisplayinit.cc ├── terminalframebuffer.cc ├── terminalframebuffer.h ├── terminalfunctions.cc ├── terminaluserinput.cc └── terminaluserinput.h ├── tests ├── .gitignore ├── Makefile.am ├── README.md ├── base64.cc ├── base64_vector.h ├── e2e-failure.test ├── e2e-success.test ├── e2e-test ├── e2e-test-server ├── e2e-test-subrs ├── emulation-80th-column.test ├── emulation-ascii-iso-8859.test ├── emulation-attributes-16color.test ├── emulation-attributes-256color248.test ├── emulation-attributes-256color8.test ├── emulation-attributes-bce.test ├── emulation-attributes-truecolor.test ├── emulation-attributes-vt100.test ├── emulation-attributes.test ├── emulation-back-tab.test ├── emulation-cursor-motion.test ├── emulation-multiline-scroll.test ├── emulation-scroll.test ├── emulation-wrap-across-frames.test ├── encrypt-decrypt.cc ├── genbase64.pl ├── hold-stdin ├── inpty.cc ├── is-utf8-locale.cc ├── local.test ├── mosh-client ├── mosh-server ├── network-no-diff.test ├── nonce-incr.cc ├── ocb-aes.cc ├── prediction-unicode.test ├── print-exitstatus ├── pty-deadlock.test ├── repeat-with-input.test ├── repeat.test ├── server-network-timeout.test ├── server-signal-timeout.test ├── test_utils.cc ├── test_utils.h ├── unicode-combine-fallback-assert.test ├── unicode-later-combining.test └── window-resize.test └── util ├── Makefile.am ├── dos_assert.h ├── fatal_assert.h ├── locale_utils.cc ├── locale_utils.h ├── pty_compat.cc ├── pty_compat.h ├── select.cc ├── select.h ├── swrite.cc ├── swrite.h ├── timestamp.cc └── timestamp.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Mozilla 4 | ColumnLimit: 116 5 | SpacesInParentheses: true 6 | AlwaysBreakAfterReturnType: None 7 | AlwaysBreakAfterDefinitionReturnType: None 8 | SpaceBeforeCpp11BracedList: true 9 | BreakBeforeBinaryOperators: All 10 | Cpp11BracedListStyle: true 11 | AllowShortBlocksOnASingleLine: Always 12 | BreakBeforeBraces: Custom 13 | BraceWrapping: 14 | AfterClass: true 15 | AfterControlStatement: Never 16 | AfterFunction: true 17 | AfterStruct: true 18 | AfterEnum: true 19 | SplitEmptyFunction: false 20 | SplitEmptyRecord: false 21 | SplitEmptyNamespace: false 22 | BreakConstructorInitializers: BeforeColon 23 | ... 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=true 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ${{ matrix.os }} 8 | 9 | strategy: 10 | matrix: 11 | os: [macos-latest, ubuntu-20.04, ubuntu-22.04] 12 | crypto: [auto] 13 | include: 14 | - crypto: nettle 15 | os: ubuntu-20.04 16 | 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - name: "setup linux build environment" 22 | if: ${{ startsWith(matrix.os, 'ubuntu') }} 23 | run: sudo apt install -y protobuf-compiler libprotobuf-dev libutempter-dev autoconf automake nettle-dev 24 | 25 | - name: "setup macos build environment" 26 | if: ${{ startsWith(matrix.os, 'macos') }} 27 | run: brew install protobuf automake 28 | 29 | - name: "generate build scripts" 30 | run: ./autogen.sh 31 | 32 | - name: ${{ format('configure (crypto {0})', matrix.crypto) }} 33 | run: ./configure --enable-compile-warnings=error --enable-examples ${{ (matrix.crypto != 'auto' && format('--with-crypto-library={0}', matrix.crypto)) || '' }} 34 | 35 | - name: "build" 36 | run: make V=1 37 | 38 | - name: "test" 39 | run: make V=1 check 40 | -------------------------------------------------------------------------------- /.github/workflows/cifuzz.yml: -------------------------------------------------------------------------------- 1 | name: CIFuzz 2 | on: [pull_request] 3 | jobs: 4 | Fuzzing: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Build Fuzzers 8 | id: build 9 | uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 10 | with: 11 | oss-fuzz-project-name: 'mosh' 12 | dry-run: false 13 | language: c++ 14 | - name: Run Fuzzers 15 | uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 16 | with: 17 | oss-fuzz-project-name: 'mosh' 18 | fuzz-seconds: 300 19 | dry-run: false 20 | language: c++ 21 | - name: Upload Crash 22 | uses: actions/upload-artifact@v3 23 | if: failure() && steps.build.outcome == 'success' 24 | with: 25 | name: artifacts 26 | path: ./out/artifacts 27 | -------------------------------------------------------------------------------- /.github/workflows/clang-format.yml: -------------------------------------------------------------------------------- 1 | name: clang-format-lint 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: DoozyX/clang-format-lint-action@v0.16.2 12 | with: 13 | source: './src' 14 | style: file 15 | clangFormatVersion: 14 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.o 3 | *.pb.cc 4 | *.pb.h 5 | *~ 6 | .deps 7 | Makefile 8 | Makefile.in 9 | .cproject 10 | .project 11 | compile_commands.json 12 | aminclude_static.am 13 | 14 | # Coverage artifacts 15 | *.gcda 16 | *.gcno 17 | *-coverage.info 18 | *-coverage 19 | 20 | /INSTALL 21 | /aclocal.m4 22 | /ar-lib 23 | /autom4te.cache 24 | /compile 25 | src/include/config.h 26 | src/include/config.h.in 27 | src/include/config.h.in~ 28 | /config.log 29 | /config.status 30 | /configure 31 | /depcomp 32 | /install-sh 33 | /missing 34 | /mosh-*.tar.gz 35 | src/include/stamp-h1 36 | /test-driver 37 | /VERSION 38 | /VERSION.stamp 39 | /scripts/mosh 40 | src/include/version.h 41 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Keith Winstein 2 | Anders Kaseorg 3 | Quentin Smith 4 | Richard Tibbetts 5 | Keegan McAllister 6 | John Hood 7 | -------------------------------------------------------------------------------- /COPYING.iOS: -------------------------------------------------------------------------------- 1 | The Mosh developers are aware that the terms of service that apply to 2 | apps distributed via Apple's App Store services may conflict with 3 | rights granted under Mosh's license, the GNU General Public License, 4 | version 3. The Mosh copyright holders do not wish this conflict to 5 | prevent the otherwise-compliant distribution of Mosh-derived apps via 6 | the App Store. Therefore, we have committed not to pursue any license 7 | violation that results solely from the conflict between the GPLv3 and 8 | the Apple App Store terms of service. In other words, as long as you 9 | comply with the GPL in all other respects, including its requirements 10 | to provide users with source code and the text of the license, we will 11 | not object to your distribution of Mosh through the App Store. 12 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Work around inconsistency in AX_CODE_COVERAGE defining 2 | # AM_DISTCHECK_CONFIGURE_FLAGS only in some branches 3 | if !CODE_COVERAGE_ENABLED 4 | AM_DISTCHECK_CONFIGURE_FLAGS = 5 | endif 6 | 7 | include $(top_srcdir)/aminclude_static.am 8 | 9 | ACLOCAL_AMFLAGS = -I m4 10 | SUBDIRS = scripts src man conf 11 | EXTRA_DIST = autogen.sh ocb-license.html README.md COPYING.iOS 12 | BUILT_SOURCES = VERSION.stamp 13 | AM_DISTCHECK_CONFIGURE_FLAGS += --enable-compile-warnings=distcheck --enable-examples --enable-syslog 14 | 15 | # AX_CODE_COVERAGE configuration 16 | 17 | # Remove everything outside of this repository 18 | CODE_COVERAGE_IGNORE_PATTERN = "/usr/include/*" "/usr/lib/*" "*/src/tests/*" "*/src/protobufs/*" 19 | 20 | # Ensure coverage is relative to the top of the repository 21 | CODE_COVERAGE_DIRECTORY = $(abs_top_builddir) 22 | 23 | # non-Automake defines 24 | CPPCHECK_FLAGS = --enable=all --template=gcc --force # -j8 disables unused function checking. 25 | CLANG_SCAN_BUILD = scan-build 26 | BEAR = bear 27 | OCLINT_JCD = oclint-json-compilation-database 28 | OCLINT_OPTIONS = -enable-global-analysis -max-priority-2=1000 -max-priority-3=1000 \ 29 | -rc LONG_LINE=160 \ 30 | -rc LONG_VARIABLE_NAME=40 \ 31 | -rc SHORT_VARIABLE_NAME=1 \ 32 | -rc MINIMUM_CASES_IN_SWITCH=2 33 | 34 | .PHONY: VERSION.stamp 35 | 36 | VERSION.stamp: 37 | @echo @PACKAGE_STRING@ > VERSION.dist 38 | @set -e; if git describe --dirty --always > VERSION.git 2>&1 && \ 39 | [ -z `git rev-parse --show-prefix` ]; then \ 40 | if ! diff -q VERSION.git VERSION.stamp > /dev/null 2>&1; then \ 41 | mv -f VERSION.git VERSION.stamp; \ 42 | fi; \ 43 | elif ! diff -q VERSION.dist VERSION.stamp > /dev/null 2>&1; then \ 44 | mv -f VERSION.dist VERSION.stamp; \ 45 | fi 46 | @rm -f VERSION.dist VERSION.git 47 | 48 | clean-local: 49 | @rm -rf VERSION.stamp cov-int mosh-coverity.txz compile_commands.json 50 | 51 | # Linters and static checkers, for development only. Not included in 52 | # build dependencies, and outside of Automake processing. 53 | cppcheck: 54 | cppcheck $(CPPCHECK_FLAGS) -include src/include/config.h -I src/include \ 55 | -I src/crypto -I src/frontend -I src/network -I src/protobufs \ 56 | -I src/statesync -I src/terminal -I src/util \ 57 | -I /usr/include -I /usr/include/google/protobuf -I/usr/include/openssl \ 58 | src 59 | 60 | # Coverity. 61 | cov-build: 62 | $(MAKE) clean 63 | rm -rf cov-int 64 | cov-build --dir cov-int $(MAKE) check TESTS= 65 | tar -caf mosh-coverity.txz cov-int 66 | 67 | # These two rules are for Bear + OCLint. 68 | # Don't *run* the tests, prediction-unicode.test generates arguments 69 | # with illegal UTF-8 that make Bear unhappy. 70 | compile_commands.json: 71 | $(MAKE) clean 72 | bear $(MAKE) check TESTS= 73 | oclint: compile_commands.json 74 | $(OCLINT_JCD) -e src/protobufs -- $(OCLINT_OPTIONS) 75 | 76 | # Clang's scan-build static checker. 77 | scan-build: 78 | $(MAKE) clean 79 | $(CLANG_SCAN_BUILD) $(MAKE) check TESTS= 80 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 2012-04-26 2 | ---------- 3 | 4 | * Version 1.2 released 5 | 6 | 2012-03-22 7 | ---------- 8 | 9 | * Version 1.1 released 10 | 11 | 2012-03-12 12 | ---------- 13 | 14 | * Version 1.0 released 15 | 16 | 2012-03-07 Release candidate (0.97): 17 | ------------------------------------ 18 | 19 | * Now builds on Mac OS X as well as GNU/Linux 20 | 21 | 2012-02-06 Initial release (0.9): 22 | --------------------------------- 23 | 24 | * Supports intermittent connectivity 25 | * Supports client and server IP roaming 26 | * Local echo supports typing and the left and right arrow keys 27 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | * Hari Balakrishnan, who advised this work and came up with the name. 2 | 3 | * Paul Williams (www.vt100.net), whose reverse-engineered vt500 state 4 | diagram is the basis for the Mosh parser. 5 | 6 | * The anonymous users who contributed session logs for tuning and 7 | measuring Mosh's predictive echo. 8 | 9 | * Nickolai Zeldovich for helpful comments on the Mosh research paper. 10 | 11 | * Richard Stallman for helpful discussion about the capabilities of 12 | the SUPDUP Local Editing Protocol. 13 | 14 | * Nelson Elhage 15 | 16 | * Christine Spang 17 | 18 | * Stefie Tellex 19 | 20 | * Joseph Sokol-Margolis 21 | 22 | * Waseem Daher 23 | 24 | * Bill McCloskey 25 | 26 | * Austin Roach 27 | 28 | * Greg Hudson 29 | 30 | * Karl Ramm 31 | 32 | * Alexander Chernyakhovsky 33 | 34 | * Peter Iannucci 35 | 36 | * Evan Broder 37 | 38 | * Neha Narula 39 | 40 | * Katrina LaCurts 41 | 42 | * Ramesh Chandra 43 | 44 | * Peter Jeremy 45 | 46 | * Ed Schouten 47 | 48 | * Ryan Steinmetz 49 | 50 | * Jay Freeman 51 | 52 | * Dave Täht 53 | 54 | * Larry Doolittle 55 | 56 | * Daniel Drown 57 | 58 | * Timo Juhani Lindfors 59 | 60 | * Timo Sirainen 61 | 62 | * Ira Cooper 63 | 64 | * Felix Gröbert 65 | 66 | * Luke Mewburn 67 | 68 | * Anton Lundin 69 | 70 | * Philipp Haselwarter 71 | 72 | * Timo J. Rinne 73 | 74 | * Barosl Lee 75 | 76 | * Andrew Chin 77 | 78 | * Louis Kruger 79 | 80 | * Jérémie Courrèges-Anglas 81 | 82 | * Pasi Sjöholm 83 | 84 | * Richard Woodbury 85 | 86 | * Igor Bukanov 87 | 88 | * Geoffrey Thomas 89 | 90 | * Steve Dignam 91 | 92 | * HIGUCHI Yuta 93 | 94 | * Baruch Siach 95 | 96 | * Adrien Destugues 97 | 98 | * Giel van Schijndel 99 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec autoreconf -fi 4 | -------------------------------------------------------------------------------- /build-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gbp buildpackage --git-upstream-branch=master --git-upstream-tree=branch 4 | -------------------------------------------------------------------------------- /build-source-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | gbp buildpackage --git-upstream-branch=master --git-upstream-tree=branch -S 4 | -------------------------------------------------------------------------------- /conf/Makefile.am: -------------------------------------------------------------------------------- 1 | completionsdir = @completions@ 2 | dist_completions_DATA = 3 | nobase_dist_sysconf_DATA = 4 | 5 | if INSTALL_UFW 6 | nobase_dist_sysconf_DATA += ufw/applications.d/mosh 7 | endif 8 | 9 | if INSTALL_COMPLETION 10 | dist_completions_DATA += bash-completion/completions/mosh 11 | endif 12 | -------------------------------------------------------------------------------- /conf/bash-completion/completions/mosh: -------------------------------------------------------------------------------- 1 | # Bash completions for Mosh, the mobile shell. -*- shell-script -*- 2 | 3 | __mosh_init_completion() 4 | { 5 | if declare -F _init_completions >/dev/null 2>&1; then 6 | _init_completion 7 | else 8 | COMPREPLY=() 9 | _get_comp_words_by_ref cur prev words cword 10 | fi 11 | } 12 | 13 | _mosh () { 14 | local cur 15 | 16 | __mosh_init_completion || return 17 | 18 | local simple_flags="-a -b -4 -6 -p" 19 | local flags="--client= --server= --predict= --family= --port= 20 | --bind-server= --ssh= --no-init --help --version" 21 | 22 | if [[ "$cur" == --* && "$COMP_CWORD" == 1 ]]; then 23 | COMPREPLY=($(compgen -W "$flags" -- "$cur")) 24 | elif [[ "$cur" == -* && "$COMP_CWORD" == 1 ]]; then 25 | COMPREPLY=($(compgen -W "$simple_flags" -- "$cur")) 26 | else 27 | _known_hosts_real -a "$cur" 28 | fi 29 | } 30 | 31 | complete -o nospace -F _mosh mosh 32 | -------------------------------------------------------------------------------- /conf/ufw/applications.d/mosh: -------------------------------------------------------------------------------- 1 | [mosh] 2 | title=Mosh (mobile shell) 3 | description=Mobile shell that supports roaming and intelligent local echo 4 | ports=60000:61000/udp 5 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: mosh 2 | Section: net 3 | Priority: optional 4 | Maintainer: Keith Winstein 5 | Uploaders: Alex Chernyakhovsky , Benjamin Barenblat 6 | Build-Depends: debhelper-compat (= 12), protobuf-compiler, libprotobuf-dev, pkg-config, libutempter-dev, zlib1g-dev, libncurses5-dev, libssl-dev, bash-completion, locales , tmux , less 7 | Rules-Requires-Root: binary-targets 8 | Standards-Version: 4.6.1 9 | Homepage: https://mosh.org 10 | Vcs-Git: https://github.com/mobile-shell/mosh.git 11 | Vcs-Browser: https://github.com/mobile-shell/mosh 12 | 13 | Package: mosh 14 | Architecture: any 15 | Pre-Depends: dpkg (>= 1.15.7.2) 16 | Depends: ${shlibs:Depends}, ${misc:Depends}, openssh-client 17 | Recommends: libio-socket-ip-perl 18 | Description: Mobile shell that supports roaming and intelligent local echo 19 | Mosh is a remote terminal application that supports: 20 | - intermittent network connectivity, 21 | - roaming to different IP address without dropping the connection, and 22 | - intelligent local echo and line editing to reduce the effects 23 | of "network lag" on high-latency connections. 24 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /debian/mosh.maintscript: -------------------------------------------------------------------------------- 1 | rm_conffile /etc/bash_completion.d/mosh 1.2.5~ 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | # Through Autoconf we set hardening flags that are actually more aggressive 13 | # than the Ubuntu defaults, but they conflict with same. 14 | export DEB_BUILD_MAINT_OPTIONS = hardening=-stackprotector 15 | -include /usr/share/dpkg/buildflags.mk 16 | 17 | %: 18 | dh $@ --with autoreconf 19 | 20 | override_dh_auto_configure: 21 | dh_auto_configure -- \ 22 | --disable-silent-rules \ 23 | --enable-ufw \ 24 | --enable-completion \ 25 | --enable-compile-warnings=error 26 | 27 | override_dh_perl: 28 | # mosh only uses Perl modules in perl-base. 29 | dh_perl -d 30 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=4 2 | opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \ 3 | https://github.com/mobile-shell/mosh/tags \ 4 | .*/mosh-(\d[\d\.]+)\.tar\.gz debian uupdate 5 | -------------------------------------------------------------------------------- /fedora/mosh.spec: -------------------------------------------------------------------------------- 1 | Name: mosh 2 | Version: 1.2.5 3 | Release: 1%{?dist} 4 | Summary: Mobile shell that supports roaming and intelligent local echo 5 | 6 | License: GPLv3+ 7 | Group: Applications/Internet 8 | URL: https://mosh.org/ 9 | Source0: https://github.com/downloads/keithw/mosh/mosh-%{version}.tar.gz 10 | 11 | BuildRequires: protobuf-compiler 12 | BuildRequires: protobuf-devel 13 | BuildRequires: libutempter-devel 14 | BuildRequires: zlib-devel 15 | BuildRequires: ncurses-devel 16 | BuildRequires: openssl-devel 17 | Requires: openssh-clients 18 | Requires: openssl 19 | Requires: perl-IO-Socket-IP 20 | 21 | %description 22 | Mosh is a remote terminal application that supports: 23 | - intermittent network connectivity, 24 | - roaming to different IP address without dropping the connection, and 25 | - intelligent local echo and line editing to reduce the effects 26 | of "network lag" on high-latency connections. 27 | 28 | 29 | %prep 30 | %setup -q 31 | 32 | 33 | %build 34 | # Use upstream's more aggressive hardening instead of Fedora's defaults 35 | export CFLAGS="-g -O2" CXXFLAGS="-g -O2" 36 | %configure --enable-compile-warnings=error 37 | make %{?_smp_mflags} 38 | 39 | 40 | %install 41 | make install DESTDIR=$RPM_BUILD_ROOT 42 | 43 | 44 | %files 45 | %doc README.md COPYING ChangeLog 46 | %{_bindir}/mosh 47 | %{_bindir}/mosh-client 48 | %{_bindir}/mosh-server 49 | %{_mandir}/man1/mosh.1.gz 50 | %{_mandir}/man1/mosh-client.1.gz 51 | %{_mandir}/man1/mosh-server.1.gz 52 | 53 | 54 | %changelog 55 | * Sun Jul 12 2015 John Hood - 1.2.5-1 56 | - Update to mosh 1.2.5 57 | 58 | * Fri Jun 26 2015 John Hood - 1.2.4.95rc2-1 59 | - Update to mosh 1.2.4.95rc2 60 | 61 | * Mon Jun 08 2015 John Hood - 1.2.4.95rc1-1 62 | - Update to mosh 1.2.4.95rc1 63 | 64 | * Wed Mar 27 2013 Alexander Chernyakhovsky - 1.2.4-1 65 | - Update to mosh 1.2.4 66 | 67 | * Sun Mar 10 2013 Alexander Chernyakhovsky - 1.2.3-3 68 | - Rebuilt for Protobuf API change from 2.4.1 to 2.5.0 69 | 70 | * Thu Feb 14 2013 Fedora Release Engineering - 1.2.3-2 71 | - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild 72 | 73 | * Fri Oct 19 2012 Alexander Chernyakhovsky - 1.2.3-1 74 | - Update to mosh 1.2.3 75 | 76 | * Fri Jul 20 2012 Fedora Release Engineering - 1.2.2-2 77 | - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild 78 | 79 | * Wed Jun 13 2012 Alexander Chernyakhovsky - 1.2.2-1 80 | - Update to mosh 1.2.2 81 | 82 | * Sat Apr 28 2012 Alexander Chernyakhovsky - 1.2-2 83 | - Add -g and -O2 CFLAGS 84 | 85 | * Fri Apr 27 2012 Alexander Chernyakhovsky - 1.2-1 86 | - Update to mosh 1.2. 87 | 88 | * Mon Mar 26 2012 Alexander Chernyakhovsky - 1.1.1-1 89 | - Update to mosh 1.1.1. 90 | 91 | * Wed Mar 21 2012 Alexander Chernyakhovsky - 1.1-1 92 | - Initial packaging for mosh. 93 | -------------------------------------------------------------------------------- /m4/ax_ac_append_to_file.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_ac_append_to_file.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_AC_APPEND_TO_FILE([FILE],[DATA]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Appends the specified data to the specified Autoconf is run. If you want 12 | # to append to a file when configure is run use AX_APPEND_TO_FILE instead. 13 | # 14 | # LICENSE 15 | # 16 | # Copyright (c) 2009 Allan Caffee 17 | # 18 | # Copying and distribution of this file, with or without modification, are 19 | # permitted in any medium without royalty provided the copyright notice 20 | # and this notice are preserved. This file is offered as-is, without any 21 | # warranty. 22 | 23 | #serial 10 24 | 25 | AC_DEFUN([AX_AC_APPEND_TO_FILE],[ 26 | AC_REQUIRE([AX_FILE_ESCAPES]) 27 | m4_esyscmd( 28 | AX_FILE_ESCAPES 29 | [ 30 | printf "%s" "$2" >> "$1" 31 | ]) 32 | ]) 33 | -------------------------------------------------------------------------------- /m4/ax_ac_print_to_file.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_ac_print_to_file.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_AC_PRINT_TO_FILE([FILE],[DATA]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Writes the specified data to the specified file when Autoconf is run. If 12 | # you want to print to a file when configure is run use AX_PRINT_TO_FILE 13 | # instead. 14 | # 15 | # LICENSE 16 | # 17 | # Copyright (c) 2009 Allan Caffee 18 | # 19 | # Copying and distribution of this file, with or without modification, are 20 | # permitted in any medium without royalty provided the copyright notice 21 | # and this notice are preserved. This file is offered as-is, without any 22 | # warranty. 23 | 24 | #serial 10 25 | 26 | AC_DEFUN([AX_AC_PRINT_TO_FILE],[ 27 | m4_esyscmd( 28 | AC_REQUIRE([AX_FILE_ESCAPES]) 29 | [ 30 | printf "%s" "$2" > "$1" 31 | ]) 32 | ]) 33 | -------------------------------------------------------------------------------- /m4/ax_add_am_macro_static.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_add_am_macro_static.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_ADD_AM_MACRO_STATIC([RULE]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Adds the specified rule to $AMINCLUDE. 12 | # 13 | # LICENSE 14 | # 15 | # Copyright (c) 2009 Tom Howard 16 | # Copyright (c) 2009 Allan Caffee 17 | # 18 | # Copying and distribution of this file, with or without modification, are 19 | # permitted in any medium without royalty provided the copyright notice 20 | # and this notice are preserved. This file is offered as-is, without any 21 | # warranty. 22 | 23 | #serial 8 24 | 25 | AC_DEFUN([AX_ADD_AM_MACRO_STATIC],[ 26 | AC_REQUIRE([AX_AM_MACROS_STATIC]) 27 | AX_AC_APPEND_TO_FILE(AMINCLUDE_STATIC,[$1]) 28 | ]) 29 | -------------------------------------------------------------------------------- /m4/ax_am_macros_static.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_am_macros_static.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_AM_MACROS_STATIC 8 | # 9 | # DESCRIPTION 10 | # 11 | # Adds support for macros that create Automake rules. You must manually 12 | # add the following line 13 | # 14 | # include $(top_srcdir)/aminclude_static.am 15 | # 16 | # to your Makefile.am files. 17 | # 18 | # LICENSE 19 | # 20 | # Copyright (c) 2009 Tom Howard 21 | # Copyright (c) 2009 Allan Caffee 22 | # 23 | # Copying and distribution of this file, with or without modification, are 24 | # permitted in any medium without royalty provided the copyright notice 25 | # and this notice are preserved. This file is offered as-is, without any 26 | # warranty. 27 | 28 | #serial 11 29 | 30 | AC_DEFUN([AMINCLUDE_STATIC],[aminclude_static.am]) 31 | 32 | AC_DEFUN([AX_AM_MACROS_STATIC], 33 | [ 34 | AX_AC_PRINT_TO_FILE(AMINCLUDE_STATIC,[ 35 | # ]AMINCLUDE_STATIC[ generated automatically by Autoconf 36 | # from AX_AM_MACROS_STATIC on ]m4_esyscmd([LC_ALL=C date])[ 37 | ]) 38 | ]) 39 | -------------------------------------------------------------------------------- /m4/ax_check_compile_flag.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check whether the given FLAG works with the current language's compiler 12 | # or gives an error. (Warnings, however, are ignored) 13 | # 14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 15 | # success/failure. 16 | # 17 | # If EXTRA-FLAGS is defined, it is added to the current language's default 18 | # flags (e.g. CFLAGS) when the check is done. The check is thus made with 19 | # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to 20 | # force the compiler to issue an error when a bad flag is given. 21 | # 22 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this 23 | # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. 24 | # 25 | # LICENSE 26 | # 27 | # Copyright (c) 2008 Guido U. Draheim 28 | # Copyright (c) 2011 Maarten Bosmans 29 | # 30 | # This program is free software: you can redistribute it and/or modify it 31 | # under the terms of the GNU General Public License as published by the 32 | # Free Software Foundation, either version 3 of the License, or (at your 33 | # option) any later version. 34 | # 35 | # This program is distributed in the hope that it will be useful, but 36 | # WITHOUT ANY WARRANTY; without even the implied warranty of 37 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 38 | # Public License for more details. 39 | # 40 | # You should have received a copy of the GNU General Public License along 41 | # with this program. If not, see . 42 | # 43 | # As a special exception, the respective Autoconf Macro's copyright owner 44 | # gives unlimited permission to copy, distribute and modify the configure 45 | # scripts that are the output of Autoconf when processing the Macro. You 46 | # need not follow the terms of the GNU General Public License when using 47 | # or distributing such scripts, even though portions of the text of the 48 | # Macro appear in them. The GNU General Public License (GPL) does govern 49 | # all other use of the material that constitutes the Autoconf Macro. 50 | # 51 | # This special exception to the GPL applies to versions of the Autoconf 52 | # Macro released by the Autoconf Archive. When you make and distribute a 53 | # modified version of the Autoconf Macro, you may extend this special 54 | # exception to the GPL to apply to your modified version as well. 55 | 56 | #serial 2 57 | 58 | AC_DEFUN([AX_CHECK_COMPILE_FLAG], 59 | [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX 60 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl 61 | AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ 62 | ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS 63 | _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" 64 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], 65 | [AS_VAR_SET(CACHEVAR,[yes])], 66 | [AS_VAR_SET(CACHEVAR,[no])]) 67 | _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) 68 | AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], 69 | [m4_default([$2], :)], 70 | [m4_default([$3], :)]) 71 | AS_VAR_POPDEF([CACHEVAR])dnl 72 | ])dnl AX_CHECK_COMPILE_FLAGS 73 | -------------------------------------------------------------------------------- /m4/ax_check_gnu_make.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CHECK_GNU_MAKE([run-if-true],[run-if-false]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # This macro searches for a GNU version of make. If a match is found: 12 | # 13 | # * The makefile variable `ifGNUmake' is set to the empty string, otherwise 14 | # it is set to "#". This is useful for including a special features in a 15 | # Makefile, which cannot be handled by other versions of make. 16 | # * The makefile variable `ifnGNUmake' is set to #, otherwise 17 | # it is set to the empty string. This is useful for including a special 18 | # features in a Makefile, which can be handled 19 | # by other versions of make or to specify else like clause. 20 | # * The variable `_cv_gnu_make_command` is set to the command to invoke 21 | # GNU make if it exists, the empty string otherwise. 22 | # * The variable `ax_cv_gnu_make_command` is set to the command to invoke 23 | # GNU make by copying `_cv_gnu_make_command`, otherwise it is unset. 24 | # * If GNU Make is found, its version is extracted from the output of 25 | # `make --version` as the last field of a record of space-separated 26 | # columns and saved into the variable `ax_check_gnu_make_version`. 27 | # * Additionally if GNU Make is found, run shell code run-if-true 28 | # else run shell code run-if-false. 29 | # 30 | # Here is an example of its use: 31 | # 32 | # Makefile.in might contain: 33 | # 34 | # # A failsafe way of putting a dependency rule into a makefile 35 | # $(DEPEND): 36 | # $(CC) -MM $(srcdir)/*.c > $(DEPEND) 37 | # 38 | # @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) 39 | # @ifGNUmake@ include $(DEPEND) 40 | # @ifGNUmake@ else 41 | # fallback code 42 | # @ifGNUmake@ endif 43 | # 44 | # Then configure.in would normally contain: 45 | # 46 | # AX_CHECK_GNU_MAKE() 47 | # AC_OUTPUT(Makefile) 48 | # 49 | # Then perhaps to cause gnu make to override any other make, we could do 50 | # something like this (note that GNU make always looks for GNUmakefile 51 | # first): 52 | # 53 | # if ! test x$_cv_gnu_make_command = x ; then 54 | # mv Makefile GNUmakefile 55 | # echo .DEFAULT: > Makefile ; 56 | # echo \ $_cv_gnu_make_command \$@ >> Makefile; 57 | # fi 58 | # 59 | # Then, if any (well almost any) other make is called, and GNU make also 60 | # exists, then the other make wraps the GNU make. 61 | # 62 | # LICENSE 63 | # 64 | # Copyright (c) 2008 John Darrington 65 | # Copyright (c) 2015 Enrico M. Crisostomo 66 | # 67 | # Copying and distribution of this file, with or without modification, are 68 | # permitted in any medium without royalty provided the copyright notice 69 | # and this notice are preserved. This file is offered as-is, without any 70 | # warranty. 71 | 72 | #serial 12 73 | 74 | AC_DEFUN([AX_CHECK_GNU_MAKE],dnl 75 | [AC_PROG_AWK 76 | AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl 77 | _cv_gnu_make_command="" ; 78 | dnl Search all the common names for GNU make 79 | for a in "$MAKE" make gmake gnumake ; do 80 | if test -z "$a" ; then continue ; fi ; 81 | if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then 82 | _cv_gnu_make_command=$a ; 83 | AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make") 84 | ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }') 85 | break ; 86 | fi 87 | done ;]) 88 | dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise 89 | AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])]) 90 | AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifnGNUmake], [""])], [AS_VAR_SET([ifnGNUmake], ["#"])]) 91 | AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])]) 92 | AS_VAR_IF([_cv_gnu_make_command], [""],[$2],[$1]) 93 | AC_SUBST([ifGNUmake]) 94 | AC_SUBST([ifnGNUmake]) 95 | ]) 96 | -------------------------------------------------------------------------------- /m4/ax_check_library.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_check_library.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CHECK_LIBRARY(VARIABLE-PREFIX, HEADER-FILE, LIBRARY-FILE, 8 | # [ACTION-IF-FOUND], [ACTION-IF-NOT_FOUND]) 9 | # 10 | # DESCRIPTION 11 | # 12 | # Provides a generic test for a given library, similar in concept to the 13 | # PKG_CHECK_MODULES macro used by pkg-config. 14 | # 15 | # Most simplest libraries can be checked against simply through the 16 | # presence of a header file and a library to link to. This macro allows to 17 | # wrap around the test so that it doesn't have to be recreated each time. 18 | # 19 | # Rather than define --with-$LIBRARY arguments, it uses variables in the 20 | # same way that PKG_CHECK_MODULES does. It doesn't, though, use the same 21 | # names, since you shouldn't provide a value for LIBS or CFLAGS but rather 22 | # for LDFLAGS and CPPFLAGS, to tell the linker and compiler where to find 23 | # libraries and headers respectively. 24 | # 25 | # If the library is find, HAVE_PREFIX is defined, and in all cases 26 | # PREFIX_LDFLAGS and PREFIX_CPPFLAGS are substituted. 27 | # 28 | # Example: 29 | # 30 | # AX_CHECK_LIBRARY([LIBEVENT], [event.h], [event], [], 31 | # [AC_MSG_ERROR([Unable to find libevent])]) 32 | # 33 | # LICENSE 34 | # 35 | # Copyright (c) 2010 Diego Elio Petteno` 36 | # 37 | # This program is free software: you can redistribute it and/or modify it 38 | # under the terms of the GNU General Public License as published by the 39 | # Free Software Foundation, either version 3 of the License, or (at your 40 | # option) any later version. 41 | # 42 | # This program is distributed in the hope that it will be useful, but 43 | # WITHOUT ANY WARRANTY; without even the implied warranty of 44 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 45 | # Public License for more details. 46 | # 47 | # You should have received a copy of the GNU General Public License along 48 | # with this program. If not, see . 49 | # 50 | # As a special exception, the respective Autoconf Macro's copyright owner 51 | # gives unlimited permission to copy, distribute and modify the configure 52 | # scripts that are the output of Autoconf when processing the Macro. You 53 | # need not follow the terms of the GNU General Public License when using 54 | # or distributing such scripts, even though portions of the text of the 55 | # Macro appear in them. The GNU General Public License (GPL) does govern 56 | # all other use of the material that constitutes the Autoconf Macro. 57 | # 58 | # This special exception to the GPL applies to versions of the Autoconf 59 | # Macro released by the Autoconf Archive. When you make and distribute a 60 | # modified version of the Autoconf Macro, you may extend this special 61 | # exception to the GPL to apply to your modified version as well. 62 | 63 | #serial 4 64 | 65 | AC_DEFUN([AX_CHECK_LIBRARY], [ 66 | AC_ARG_VAR($1[_CPPFLAGS], [C preprocessor flags for ]$1[ headers]) 67 | AC_ARG_VAR($1[_LDFLAGS], [linker flags for ]$1[ libraries]) 68 | 69 | AC_CACHE_VAL(AS_TR_SH([ax_cv_have_]$1), 70 | [save_CPPFLAGS="$CPPFLAGS" 71 | save_LDFLAGS="$LDFLAGS" 72 | save_LIBS="$LIBS" 73 | 74 | AS_IF([test "x$]$1[_CPPFLAGS" != "x"], 75 | [CPPFLAGS="$CPPFLAGS $]$1[_CPPFLAGS"]) 76 | 77 | AS_IF([test "x$]$1[_LDFLAGS" != "x"], 78 | [LDFLAGS="$LDFLAGS $]$1[_LDFLAGS"]) 79 | 80 | AC_CHECK_HEADER($2, [ 81 | AC_CHECK_LIB($3, [main], 82 | [AS_TR_SH([ax_cv_have_]$1)=yes], 83 | [AS_TR_SH([ax_cv_have_]$1)=no]) 84 | ], [AS_TR_SH([ax_cv_have_]$1)=no]) 85 | 86 | CPPFLAGS="$save_CPPFLAGS" 87 | LDFLAGS="$save_LDFLAGS" 88 | LIBS="$save_LIBS" 89 | ]) 90 | 91 | AS_IF([test "$]AS_TR_SH([ax_cv_have_]$1)[" = "yes"], 92 | AC_DEFINE([HAVE_]$1, [1], [Define to 1 if ]$1[ is found]) 93 | [$4], 94 | [$5]) 95 | ]) 96 | -------------------------------------------------------------------------------- /m4/ax_check_link_flag.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check whether the given FLAG works with the linker or gives an error. 12 | # (Warnings, however, are ignored) 13 | # 14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 15 | # success/failure. 16 | # 17 | # If EXTRA-FLAGS is defined, it is added to the linker's default flags 18 | # when the check is done. The check is thus made with the flags: "LDFLAGS 19 | # EXTRA-FLAGS FLAG". This can for example be used to force the linker to 20 | # issue an error when a bad flag is given. 21 | # 22 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this 23 | # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. 24 | # 25 | # LICENSE 26 | # 27 | # Copyright (c) 2008 Guido U. Draheim 28 | # Copyright (c) 2011 Maarten Bosmans 29 | # 30 | # This program is free software: you can redistribute it and/or modify it 31 | # under the terms of the GNU General Public License as published by the 32 | # Free Software Foundation, either version 3 of the License, or (at your 33 | # option) any later version. 34 | # 35 | # This program is distributed in the hope that it will be useful, but 36 | # WITHOUT ANY WARRANTY; without even the implied warranty of 37 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 38 | # Public License for more details. 39 | # 40 | # You should have received a copy of the GNU General Public License along 41 | # with this program. If not, see . 42 | # 43 | # As a special exception, the respective Autoconf Macro's copyright owner 44 | # gives unlimited permission to copy, distribute and modify the configure 45 | # scripts that are the output of Autoconf when processing the Macro. You 46 | # need not follow the terms of the GNU General Public License when using 47 | # or distributing such scripts, even though portions of the text of the 48 | # Macro appear in them. The GNU General Public License (GPL) does govern 49 | # all other use of the material that constitutes the Autoconf Macro. 50 | # 51 | # This special exception to the GPL applies to versions of the Autoconf 52 | # Macro released by the Autoconf Archive. When you make and distribute a 53 | # modified version of the Autoconf Macro, you may extend this special 54 | # exception to the GPL to apply to your modified version as well. 55 | 56 | #serial 2 57 | 58 | AC_DEFUN([AX_CHECK_LINK_FLAG], 59 | [AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl 60 | AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ 61 | ax_check_save_flags=$LDFLAGS 62 | LDFLAGS="$LDFLAGS $4 $1" 63 | AC_LINK_IFELSE([AC_LANG_PROGRAM()], 64 | [AS_VAR_SET(CACHEVAR,[yes])], 65 | [AS_VAR_SET(CACHEVAR,[no])]) 66 | LDFLAGS=$ax_check_save_flags]) 67 | AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], 68 | [m4_default([$2], :)], 69 | [m4_default([$3], :)]) 70 | AS_VAR_POPDEF([CACHEVAR])dnl 71 | ])dnl AX_CHECK_LINK_FLAGS 72 | -------------------------------------------------------------------------------- /m4/ax_file_escapes.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_file_escapes.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_FILE_ESCAPES 8 | # 9 | # DESCRIPTION 10 | # 11 | # Writes the specified data to the specified file. 12 | # 13 | # LICENSE 14 | # 15 | # Copyright (c) 2008 Tom Howard 16 | # 17 | # Copying and distribution of this file, with or without modification, are 18 | # permitted in any medium without royalty provided the copyright notice 19 | # and this notice are preserved. This file is offered as-is, without any 20 | # warranty. 21 | 22 | #serial 8 23 | 24 | AC_DEFUN([AX_FILE_ESCAPES],[ 25 | AX_DOLLAR="\$" 26 | AX_SRB="\\135" 27 | AX_SLB="\\133" 28 | AX_BS="\\\\" 29 | AX_DQ="\"" 30 | ]) 31 | -------------------------------------------------------------------------------- /m4/ax_require_defined.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_require_defined.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_REQUIRE_DEFINED(MACRO) 8 | # 9 | # DESCRIPTION 10 | # 11 | # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have 12 | # been defined and thus are available for use. This avoids random issues 13 | # where a macro isn't expanded. Instead the configure script emits a 14 | # non-fatal: 15 | # 16 | # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found 17 | # 18 | # It's like AC_REQUIRE except it doesn't expand the required macro. 19 | # 20 | # Here's an example: 21 | # 22 | # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) 23 | # 24 | # LICENSE 25 | # 26 | # Copyright (c) 2014 Mike Frysinger 27 | # 28 | # Copying and distribution of this file, with or without modification, are 29 | # permitted in any medium without royalty provided the copyright notice 30 | # and this notice are preserved. This file is offered as-is, without any 31 | # warranty. 32 | 33 | #serial 2 34 | 35 | AC_DEFUN([AX_REQUIRE_DEFINED], [dnl 36 | m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) 37 | ])dnl AX_REQUIRE_DEFINED 38 | -------------------------------------------------------------------------------- /macosx/.gitignore: -------------------------------------------------------------------------------- 1 | /mosh-package.pmdoc 2 | /Mosh*.pkg 3 | /prefix*/ 4 | /Distribution 5 | /Resources/ 6 | -------------------------------------------------------------------------------- /macosx/Distribution.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | @PACKAGE_VERSION@ 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | #edu.mit.mosh.mosh.pkg 15 | 16 | -------------------------------------------------------------------------------- /macosx/brew-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Install Homebrew dependencies 5 | # 6 | # This script handles build dependencies other than those provided by 7 | # MacOS and Xcode, for a Mosh build using macosx/build.sh or the 8 | # native autoconf/automake build for CI. It is intended to be used by 9 | # a build system, and should be agnostic to any particular system. 10 | # 11 | # Similar scripts could be developed for MacPorts, direct dependency 12 | # builds, etc. 13 | # 14 | 15 | # 16 | # Install and/or configure the system used to provide dependencies. 17 | # 18 | install() 19 | { 20 | # Straight from https://brew.sh 21 | if ! brew --version > /dev/null 2>&1; then 22 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 23 | fi 24 | } 25 | 26 | # 27 | # Install up-to-date build dependencies required for a development or 28 | # CI build. These dependencies only need to provide runtime 29 | # dependencies for the build system, support for things like previous 30 | # OS versions and fat binaries is not needed. 31 | # 32 | deps() 33 | { 34 | brew update 35 | brew update 36 | brew upgrade 37 | brew reinstall tmux 38 | brew reinstall protobuf 39 | } 40 | 41 | # 42 | # Install build dependencies required for the MacOS package build. 43 | # Runtime dependencies are required to support the targeted OS X 44 | # version, static libraries, and fat binaries for the package build. 45 | # 46 | # This reinstalls protobuf with --universal --build-bottle to get a 47 | # fat library that will run on any machine. (This takes about 15 48 | # minutes on current Travis infrastructure.) 49 | # 50 | package_deps() 51 | { 52 | deps 53 | brew rm protobuf 54 | brew install protobuf --universal --build-bottle 55 | } 56 | 57 | # 58 | # Describe the dependencies installed and used as best as possible. 59 | # 60 | describe() 61 | { 62 | brew --version > brew-version.txt 63 | brew info --json=v1 --installed > brew-info.json 64 | } 65 | 66 | # 67 | # Do something. 68 | # 69 | set -e 70 | "$@" 71 | -------------------------------------------------------------------------------- /macosx/gtar: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec sudo /usr/local/bin/gtar.orig "$@" 3 | -------------------------------------------------------------------------------- /macosx/mosh-package.pmdoc.in/01prefix-contents.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | group 7 | owner 8 | 9 | 10 | group 11 | owner 12 | 13 | 14 | group 15 | owner 16 | 17 | group 18 | owner 19 | 20 | 21 | 22 | 23 | 24 | group 25 | owner 26 | 27 | 28 | group 29 | owner 30 | 31 | 32 | group 33 | owner 34 | 35 | group 36 | owner 37 | 38 | group 39 | owner 40 | 41 | group 42 | owner 43 | 44 | group 45 | owner 46 | 47 | group 48 | owner 49 | 50 | 51 | -------------------------------------------------------------------------------- /macosx/mosh-package.pmdoc.in/01prefix.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | edu.mit.mosh.mosh.pkg 4 | $PACKAGE_VERSION 5 | 6 | 7 | 8 | prefix 9 | /usr 10 | 11 | 12 | 13 | 14 | 15 | installTo 16 | relocatable 17 | installFrom.path 18 | identifier 19 | parent 20 | includeRoot 21 | installTo.path 22 | installFrom.isRelativeType 23 | version 24 | 25 | 26 | 01prefix-contents.xml 27 | /\.gitignore$ 28 | /\.DS_Store$ 29 | 30 | 31 | -------------------------------------------------------------------------------- /macosx/mosh-package.pmdoc.in/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mosh $PACKAGE_VERSION 4 | Mosh.pkg 5 | edu.mit.mosh 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Mosh is a remote terminal application that supports intermittent connectivity, allows roaming, and provides speculative local echo and line editing of user keystrokes. 15 | 16 | 17 | / 18 | 19 | 20 | 21 | 22 | 23 | copying.rtf 24 | readme.rtf 25 | 26 | 27 | 28 | 01prefix.xml 29 | properties.title 30 | properties.userDomain 31 | description 32 | 33 | -------------------------------------------------------------------------------- /macosx/osx-xcode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # OS X and Xcode support script. 5 | # 6 | 7 | # 8 | # Describe the OS X and Xcode installation, patches, etc as best as possible. 9 | # 10 | # Beware: System Profiler dumps significant private and security information. 11 | # 12 | describe() 13 | { 14 | # Most of the XML in this report is plist files, which can be read more easily with plutil -p 15 | pkgutil --pkgs-plist > packages-plist.xml 16 | mkdir package-info-plist/ 17 | for i in $(pkgutil --pkgs); do pkgutil --pkg-info-plist=$i > package-info-plist/$i.xml; done 18 | xcodebuild -version > xcodebuild-version.txt 19 | # CLT info can be found in package-info-plist/com.apple.pkg.CLTools_Executables.xml 20 | xcode-select --print-path > xcode-path.txt 21 | # System Profiler's XML can be read more easily with plutil -p, or 22 | # opened with the System Profiler GUI. 23 | system_profiler -xml -detailLevel full > system-profile.spx 2>/dev/null 24 | } 25 | 26 | # 27 | # Do something. 28 | # 29 | set -e 30 | "$@" 31 | -------------------------------------------------------------------------------- /macosx/port-deps.sh: -------------------------------------------------------------------------------- 1 | describe() { 2 | /opt/local/bin/port version > port-version.txt 3 | /opt/local/bin/port -v -q installed > port-packages.txt 4 | } 5 | 6 | deps() { 7 | # Set up macports to respect the deployment target before building universal packages 8 | echo "macosx_deployment_target 11.0" | sudo tee -a /opt/local/etc/macports/macports.conf 9 | sudo /opt/local/bin/port install protobuf3-cpp +universal 10 | sudo /opt/local/bin/port install ncurses +universal 11 | sudo /opt/local/bin/port install pkgconfig 12 | sudo /opt/local/bin/port install autoconf automake 13 | } 14 | 15 | set -e 16 | "$@" 17 | -------------------------------------------------------------------------------- /man/Makefile.am: -------------------------------------------------------------------------------- 1 | dist_man_MANS = 2 | 3 | if BUILD_CLIENT 4 | dist_man_MANS += mosh.1 mosh-client.1 5 | endif 6 | 7 | if BUILD_SERVER 8 | dist_man_MANS += mosh-server.1 9 | endif 10 | -------------------------------------------------------------------------------- /man/mosh-client.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .\" First parameter, NAME, should be all caps 3 | .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection 4 | .\" other parameters are allowed: see man(7), man(1) 5 | .TH MOSH 1 "February 2012" 6 | .\" Please adjust this date whenever revising the manpage. 7 | .\" 8 | .\" Some roff macros, for reference: 9 | .\" .nh disable hyphenation 10 | .\" .hy enable hyphenation 11 | .\" .ad l left justify 12 | .\" .ad b justify to both left and right margins 13 | .\" .nf disable filling 14 | .\" .fi enable filling 15 | .\" .br insert line break 16 | .\" .sp insert n+1 empty lines 17 | .\" for manpage-specific macros, see man(7) 18 | .SH NAME 19 | mosh-client \- client-side helper for mosh 20 | .SH SYNOPSIS 21 | MOSH_KEY=KEY 22 | .B mosh-client 23 | [\-v] 24 | IP PORT 25 | .br 26 | .B mosh-client 27 | \-c 28 | .br 29 | .SH DESCRIPTION 30 | \fBmosh-client\fP is a helper program for the 31 | .BR mosh (1) 32 | remote terminal application. 33 | 34 | \fBmosh\fP itself is a setup script that establishes an SSH 35 | connection, runs the server-side helper \fBmosh-server\fP, 36 | and collects the server's port number and session key. 37 | 38 | \fBmosh\fP then executes \fBmosh-client\fP with the server's IP 39 | address, port, and session key. \fBmosh-client\fP runs for 40 | the lifetime of the connection. 41 | 42 | The 22-byte base64 session key given by \fBmosh-server\fP is supplied 43 | in the MOSH_KEY environment variable. This represents a 128-bit AES 44 | key that protects the integrity and confidentiality of the session. 45 | 46 | For constructing new setup wrappers for remote execution facilities 47 | other than SSH, it may be necessary to invoke \fBmosh-client\fP 48 | directly. 49 | 50 | With the \-c option, \fBmosh-client\fP instead prints the number of colors 51 | of the terminal given by the TERM environment variable. 52 | 53 | The \-v option will print some debugging information on standard 54 | error. More instances of this flag will result in more debugging 55 | information. If standard error is not redirected from the terminal, 56 | the display will be corrupted and quickly become unusable. 57 | 58 | .SH ENVIRONMENT VARIABLES 59 | 60 | .TP 61 | .B MOSH_KEY 62 | This variable must be set, and must contain a Base64-encoded cryptographic key from 63 | .BR mosh-server (1). 64 | 65 | .TP 66 | .B MOSH_ESCAPE_KEY 67 | See 68 | .BR mosh (1). 69 | 70 | .TP 71 | .B MOSH_PREDICTION_DISPLAY 72 | Controls local echo as described in 73 | .BR mosh (1). 74 | 75 | .TP 76 | .B MOSH_PREDICTION_OVERWRITE 77 | Controls local echo insert/overwrite as described in 78 | .BR mosh (1). 79 | 80 | .TP 81 | .B MOSH_TITLE_NOPREFIX 82 | See 83 | .BR mosh (1). 84 | 85 | 86 | .SH SEE ALSO 87 | .BR mosh (1), 88 | .BR mosh-server (1). 89 | 90 | Project home page: 91 | .I https://mosh.org 92 | 93 | .br 94 | .SH AUTHOR 95 | mosh was written by Keith Winstein . 96 | .SH BUGS 97 | Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe 98 | to the 99 | .nh 100 | .I mosh-users@mit.edu 101 | .hy 102 | mailing list, at 103 | .br 104 | .nh 105 | .I http://mailman.mit.edu/mailman/listinfo/mosh-users 106 | .hy 107 | . 108 | -------------------------------------------------------------------------------- /ocb-license.html: -------------------------------------------------------------------------------- 1 | OCB - An Authenticated-Encryption Scheme - GPL Patent Grant - Rogaway 2 | 3 | 4 |

OCB: 5 | Patent Grant for GNU GPL

6 | 7 | Whereas I, Phillip Rogaway (hereinafter "Inventor") have sought 8 | patent protection for certain technology 9 | (hereinafter "Patented Technology"), 10 | and Inventor wishes to aid the Free Software Foundation in achieving its goals, 11 | and Inventor wishes to increase public awareness of Patented Technology, 12 | Inventor hereby grants a fully paid-up, nonexclusive, 13 | royalty-free license to 14 | practice any patents claiming priority to the 15 | patent applications below ("the Patents") 16 | if practiced by 17 | software distributed 18 | under the terms of any version of 19 | the GNU General Public License as published by the Free Software Foundation, 20 | 59 Temple Place, Suite 330, Boston, MA 02111. 21 | Inventor reserves all other rights, including without limitation 22 | licensing for software not distributed under the GNU General Public License. 23 | 24 |

The patents:

25 | 26 | 27 |
    28 |
  • 29 | 09/918,615 - 30 | Method and Apparatus for Facilitating Efficient Authenticated Encryption. 31 | 32 |
  • 33 | 09/948,084 - 34 | Method and Apparatus for Realizing a Parallelizable Variable-Input-Length 35 | Pseudorandom Function. 36 |
37 | 38 |
39 | 40 |

June 12, 2012: Phillip Rogaway licensed the distribution of OCB 41 | in Mosh under the GPL with the OpenSSL linking exception and iOS 42 | waiver contained in the COPYING.iOS file.

43 | 44 |
45 | "Mosh with the two GPL exemptions you specify in the attached note 46 | is freely licensed to use for any OCB-related IP that I own." 47 |
48 | -------------------------------------------------------------------------------- /scripts/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = wrap-compiler-for-flag-check mosh.pl 2 | if BUILD_CLIENT 3 | bin_SCRIPTS = mosh 4 | endif 5 | CLEANFILES = $(bin_SCRIPTS) 6 | 7 | mosh: mosh.pl ../VERSION.stamp Makefile 8 | perl -Mdiagnostics -c $(srcdir)/mosh.pl 9 | @sed -e "s/\@VERSION\@/`cat ../VERSION.stamp`/" -e "s/\@PACKAGE_STRING\@/@PACKAGE_STRING@/" $(srcdir)/mosh.pl > mosh 10 | @chmod a+x mosh 11 | -------------------------------------------------------------------------------- /scripts/wrap-compiler-for-flag-check: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # There is no way to make clang's "argument unused" warning fatal. So when 4 | # configure checks for supported flags, it runs $CXX and $LD via this 5 | # wrapper. 6 | # 7 | # Ideally the search string would also include 'clang: ' but this output might 8 | # depend on clang's argv[0]. 9 | 10 | if out=$("$@" 2>&1); then 11 | echo "$out" 12 | if echo "$out" | grep 'warning: argument unused' >/dev/null; then 13 | echo "$0: found clang warning" 14 | exit 1 15 | else 16 | exit 0 17 | fi 18 | else 19 | code=$? 20 | echo "$out" 21 | exit $code 22 | fi 23 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = include protobufs util crypto terminal network statesync frontend examples tests fuzz 2 | -------------------------------------------------------------------------------- /src/crypto/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/ $(CRYPTO_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshcrypto.a 5 | 6 | OCB_SRCS = ae.h 7 | if USE_AES_OCB_FROM_OPENSSL 8 | OCB_SRCS += ocb_openssl.cc 9 | else 10 | OCB_SRCS += ocb_internal.cc 11 | endif 12 | 13 | libmoshcrypto_a_SOURCES = \ 14 | $(OCB_SRCS) \ 15 | base64.cc \ 16 | base64.h \ 17 | byteorder.h \ 18 | crypto.cc \ 19 | crypto.h \ 20 | prng.h 21 | -------------------------------------------------------------------------------- /src/crypto/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | 35 | bool base64_decode( const char* b64, const size_t b64_len, uint8_t* raw, size_t* raw_len ); 36 | 37 | void base64_encode( const uint8_t* raw, const size_t raw_len, char* b64, const size_t b64_len ); 38 | -------------------------------------------------------------------------------- /src/crypto/byteorder.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef BYTEORDER_HPP 34 | #define BYTEORDER_HPP 35 | 36 | #include "src/include/config.h" 37 | 38 | #if HAVE_DECL_BE64TOH || HAVE_DECL_BETOH64 39 | 40 | #if defined( HAVE_ENDIAN_H ) 41 | #include 42 | #elif defined( HAVE_SYS_ENDIAN_H ) 43 | #include 44 | #include 45 | #endif 46 | 47 | #if !HAVE_DECL_BE64TOH && HAVE_DECL_BETOH64 48 | #define be64toh betoh64 49 | #define be16toh betoh16 50 | #endif 51 | 52 | #elif HAVE_OSX_SWAP 53 | #include 54 | #define htobe64 OSSwapHostToBigInt64 55 | #define be64toh OSSwapBigToHostInt64 56 | #define htobe16 OSSwapHostToBigInt16 57 | #define be16toh OSSwapBigToHostInt16 58 | 59 | #else 60 | 61 | /* Use our fallback implementation, which is correct for any endianness. */ 62 | 63 | #include 64 | 65 | /* Make sure they aren't macros */ 66 | #undef htobe64 67 | #undef be64toh 68 | #undef htobe16 69 | #undef be16toh 70 | 71 | /* Use unions rather than casts, to comply with strict aliasing rules. */ 72 | 73 | inline uint64_t htobe64( uint64_t x ) 74 | { 75 | uint8_t xs[8] = { static_cast( ( x >> 56 ) & 0xFF ), 76 | static_cast( ( x >> 48 ) & 0xFF ), 77 | static_cast( ( x >> 40 ) & 0xFF ), 78 | static_cast( ( x >> 32 ) & 0xFF ), 79 | static_cast( ( x >> 24 ) & 0xFF ), 80 | static_cast( ( x >> 16 ) & 0xFF ), 81 | static_cast( ( x >> 8 ) & 0xFF ), 82 | static_cast( (x)&0xFF ) }; 83 | union { 84 | const uint8_t* p8; 85 | const uint64_t* p64; 86 | } u; 87 | u.p8 = xs; 88 | return *u.p64; 89 | } 90 | 91 | inline uint64_t be64toh( uint64_t x ) 92 | { 93 | union { 94 | const uint8_t* p8; 95 | const uint64_t* p64; 96 | } u; 97 | u.p64 = &x; 98 | return ( uint64_t( u.p8[0] ) << 56 ) | ( uint64_t( u.p8[1] ) << 48 ) | ( uint64_t( u.p8[2] ) << 40 ) 99 | | ( uint64_t( u.p8[3] ) << 32 ) | ( uint64_t( u.p8[4] ) << 24 ) | ( uint64_t( u.p8[5] ) << 16 ) 100 | | ( uint64_t( u.p8[6] ) << 8 ) | ( uint64_t( u.p8[7] ) ); 101 | } 102 | 103 | inline uint16_t htobe16( uint16_t x ) 104 | { 105 | uint8_t xs[2] = { static_cast( ( x >> 8 ) & 0xFF ), static_cast( (x)&0xFF ) }; 106 | union { 107 | const uint8_t* p8; 108 | const uint16_t* p16; 109 | } u; 110 | u.p8 = xs; 111 | return *u.p16; 112 | } 113 | 114 | inline uint16_t be16toh( uint16_t x ) 115 | { 116 | union { 117 | const uint8_t* p8; 118 | const uint16_t* p16; 119 | } u; 120 | u.p16 = &x; 121 | return ( uint16_t( u.p8[0] ) << 8 ) | ( uint16_t( u.p8[1] ) ); 122 | } 123 | 124 | #endif 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/crypto/prng.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PRNG_HPP 34 | #define PRNG_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "src/crypto/crypto.h" 41 | 42 | /* Read random bytes from /dev/urandom. 43 | 44 | We rely on stdio buffering for efficiency. */ 45 | 46 | static const char rdev[] = "/dev/urandom"; 47 | 48 | using namespace Crypto; 49 | 50 | class PRNG 51 | { 52 | private: 53 | std::ifstream randfile; 54 | 55 | /* unimplemented to satisfy -Weffc++ */ 56 | PRNG( const PRNG& ); 57 | PRNG& operator=( const PRNG& ); 58 | 59 | public: 60 | PRNG() : randfile( rdev, std::ifstream::in | std::ifstream::binary ) {} 61 | 62 | void fill( void* dest, size_t size ) 63 | { 64 | if ( 0 == size ) { 65 | return; 66 | } 67 | 68 | randfile.read( static_cast( dest ), size ); 69 | if ( !randfile ) { 70 | throw CryptoException( "Could not read from " + std::string( rdev ) ); 71 | } 72 | } 73 | 74 | uint8_t uint8() 75 | { 76 | uint8_t x; 77 | fill( &x, 1 ); 78 | return x; 79 | } 80 | 81 | uint32_t uint32() 82 | { 83 | uint32_t x; 84 | fill( &x, 4 ); 85 | return x; 86 | } 87 | 88 | uint64_t uint64() 89 | { 90 | uint64_t x; 91 | fill( &x, 8 ); 92 | return x; 93 | } 94 | }; 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/examples/.gitignore: -------------------------------------------------------------------------------- 1 | /decrypt 2 | /encrypt 3 | /ntester 4 | /parse 5 | /termemu 6 | /benchmark 7 | -------------------------------------------------------------------------------- /src/examples/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = -I$(top_srcdir)/ $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) 2 | AM_LDFLAGS = $(HARDEN_LDFLAGS) 3 | 4 | if BUILD_EXAMPLES 5 | noinst_PROGRAMS = encrypt decrypt ntester parse termemu benchmark 6 | endif 7 | 8 | encrypt_SOURCES = encrypt.cc 9 | encrypt_CPPFLAGS = -I$(srcdir)/../crypto 10 | encrypt_LDADD = ../crypto/libmoshcrypto.a $(CRYPTO_LIBS) 11 | 12 | decrypt_SOURCES = decrypt.cc 13 | decrypt_CPPFLAGS = -I$(srcdir)/../crypto 14 | decrypt_LDADD = ../crypto/libmoshcrypto.a $(CRYPTO_LIBS) 15 | 16 | parse_SOURCES = parse.cc 17 | parse_CPPFLAGS = -I$(srcdir)/../terminal -I$(srcdir)/../util 18 | parse_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a 19 | 20 | termemu_SOURCES = termemu.cc 21 | termemu_CPPFLAGS = -I$(srcdir)/../terminal -I$(srcdir)/../util -I$(srcdir)/../statesync -I../protobufs 22 | termemu_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a ../statesync/libmoshstatesync.a ../protobufs/libmoshprotos.a $(TINFO_LIBS) $(protobuf_LIBS) 23 | 24 | ntester_SOURCES = ntester.cc 25 | ntester_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I../protobufs $(protobuf_CFLAGS) 26 | ntester_LDADD = ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../network/libmoshnetwork.a ../crypto/libmoshcrypto.a ../protobufs/libmoshprotos.a ../util/libmoshutil.a -lm $(protobuf_LIBS) $(CRYPTO_LIBS) 27 | 28 | benchmark_SOURCES = benchmark.cc 29 | benchmark_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I../protobufs -I$(srcdir)/../frontend -I$(srcdir)/../crypto -I$(srcdir)/../network $(protobuf_CFLAGS) 30 | benchmark_LDADD = ../frontend/terminaloverlay.o ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../protobufs/libmoshprotos.a ../network/libmoshnetwork.a ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(STDDJB_LDFLAGS) -lm $(TINFO_LIBS) $(protobuf_LIBS) $(CRYPTO_LIBS) 31 | -------------------------------------------------------------------------------- /src/examples/decrypt.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include "src/crypto/crypto.h" 38 | 39 | using namespace Crypto; 40 | 41 | int main( int argc, char* argv[] ) 42 | { 43 | if ( argc != 2 ) { 44 | fprintf( stderr, "Usage: %s KEY\n", argv[0] ); 45 | return 1; 46 | } 47 | 48 | try { 49 | Base64Key key( argv[1] ); 50 | Session session( key ); 51 | 52 | /* Read input */ 53 | std::ostringstream input; 54 | input << std::cin.rdbuf(); 55 | 56 | /* Decrypt message */ 57 | 58 | Message message = session.decrypt( input.str() ); 59 | 60 | fprintf( stderr, "Nonce = %ld\n", (long)message.nonce.val() ); 61 | std::cout << message.text; 62 | } catch ( const CryptoException& e ) { 63 | std::cerr << e.what() << std::endl; 64 | exit( 1 ); 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /src/examples/encrypt.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include "src/crypto/crypto.h" 38 | 39 | using namespace Crypto; 40 | 41 | int main( int argc, char* argv[] ) 42 | { 43 | if ( argc != 2 ) { 44 | fprintf( stderr, "Usage: %s NONCE\n", argv[0] ); 45 | return 1; 46 | } 47 | 48 | try { 49 | Base64Key key; 50 | Session session( key ); 51 | Nonce nonce( myatoi( argv[1] ) ); 52 | 53 | /* Read input */ 54 | std::ostringstream input; 55 | input << std::cin.rdbuf(); 56 | 57 | /* Encrypt message */ 58 | 59 | std::string ciphertext = session.encrypt( Message( nonce, input.str() ) ); 60 | 61 | std::cerr << "Key: " << key.printable_key() << std::endl; 62 | 63 | std::cout << ciphertext; 64 | } catch ( const CryptoException& e ) { 65 | std::cerr << e.what() << std::endl; 66 | exit( 1 ); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | /mosh-client 2 | /mosh-server 3 | -------------------------------------------------------------------------------- /src/frontend/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/ $(TINFO_CFLAGS) $(protobuf_CFLAGS) $(CRYPTO_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 3 | AM_LDFLAGS = $(HARDEN_LDFLAGS) $(CODE_COVERAGE_LIBS) 4 | LDADD = ../crypto/libmoshcrypto.a ../network/libmoshnetwork.a ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../util/libmoshutil.a ../protobufs/libmoshprotos.a -lm $(TINFO_LIBS) $(protobuf_LIBS) $(CRYPTO_LIBS) 5 | 6 | mosh_server_LDADD = $(LDADD) 7 | 8 | bin_PROGRAMS = 9 | 10 | if BUILD_CLIENT 11 | bin_PROGRAMS += mosh-client 12 | endif 13 | 14 | if BUILD_SERVER 15 | bin_PROGRAMS += mosh-server 16 | endif 17 | 18 | mosh_client_SOURCES = mosh-client.cc stmclient.cc stmclient.h terminaloverlay.cc terminaloverlay.h 19 | mosh_server_SOURCES = mosh-server.cc 20 | -------------------------------------------------------------------------------- /src/fuzz/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) $(FUZZING_CFLAGS) 2 | 3 | if ENABLE_FUZZING 4 | noinst_PROGRAMS = terminal_parser_fuzzer terminal_fuzzer 5 | endif 6 | 7 | terminal_parser_fuzzer_CPPFLAGS = -I$(top_srcdir)/ 8 | terminal_parser_fuzzer_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a 9 | terminal_parser_fuzzer_SOURCES = terminal_parser_fuzzer.cc 10 | 11 | terminal_fuzzer_CPPFLAGS = -I$(top_srcdir)/ 12 | terminal_fuzzer_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a ../statesync/libmoshstatesync.a ../protobufs/libmoshprotos.a $(TINFO_LIBS) $(protobuf_LIBS) 13 | terminal_fuzzer_SOURCES = terminal_fuzzer.cc 14 | -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/3769c52698d426976ee402b9dbc3c2a7bd5e5485: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/3769c52698d426976ee402b9dbc3c2a7bd5e5485 -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/3a52ce780950d4d969792a2559cd519d7ee8c727: -------------------------------------------------------------------------------- 1 | . -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/3facad9d449f8b10a2d18ef821325639214afc3c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/3facad9d449f8b10a2d18ef821325639214afc3c -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/433f367f36f48f78570c2013fef7a4f4b52b7c0c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/433f367f36f48f78570c2013fef7a4f4b52b7c0c -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/64b6cc492319c39d017963ee8f5863520eb7b6b9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/64b6cc492319c39d017963ee8f5863520eb7b6b9 -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/7c4d33785daa5c2370201ffa236b427aa37c9996: -------------------------------------------------------------------------------- 1 | & -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/7fff5c5bdfcaecbe749a7eda1f831a4b0ac6c285: -------------------------------------------------------------------------------- 1 | 2 | * -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/94fc46a4dd7043c8a22bc85f24aafdf0bc963125: -------------------------------------------------------------------------------- 1 | *& -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/9a78211436f6d425ec38f5c4e02270801f3524f8: -------------------------------------------------------------------------------- 1 | @ -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/a70a7fcfa8e88039504b6a798314285419f51e16: -------------------------------------------------------------------------------- 1 | 2 | 3 | @ -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/bf72240ede73688a77e62c38b4a112f15cb61802: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/bf72240ede73688a77e62c38b4a112f15cb61802 -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/c822a8bc8c7d9f938990c2bfd0b24fd9d48af917: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @@& -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/e0d3c08cb28736844512c52dc05fa4e4efd91490: -------------------------------------------------------------------------------- 1 | 2 | @ -------------------------------------------------------------------------------- /src/fuzz/terminal_corpus/f195c020a28dfc5f2fb6af256b524ddcd93756ed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_corpus/f195c020a28dfc5f2fb6af256b524ddcd93756ed -------------------------------------------------------------------------------- /src/fuzz/terminal_fuzzer.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "src/statesync/completeterminal.h" 5 | #include "src/terminal/parser.h" 6 | 7 | extern "C" int LLVMFuzzerTestOneInput( const uint8_t* data, size_t size ) 8 | { 9 | Terminal::Display display( false ); 10 | Terminal::Complete complete( 80, 24 ); 11 | Terminal::Framebuffer state( 80, 24 ); 12 | for ( size_t i = 0; i < size; i++ ) { 13 | complete.act( Parser::UserByte( data[i] ) ); 14 | } 15 | display.new_frame( true, state, complete.get_fb() ); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/7164cb6ab7e834fa6145bcf283e94b981313980d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/7164cb6ab7e834fa6145bcf283e94b981313980d -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/71853c6197a6a7f222db0f1978c7cb232b87c5ee: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/7b98b1bb85d1afb4f154cfbe9c3d4791024a86b7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/7b98b1bb85d1afb4f154cfbe9c3d4791024a86b7 -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/8a92b4d6e188b3e2fa7add9e123b702ed11f3695: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/8a92b4d6e188b3e2fa7add9e123b702ed11f3695 -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/99feeb7f36e52ff59d86c975a8e5ad1a2ab4629e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/99feeb7f36e52ff59d86c975a8e5ad1a2ab4629e -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/9d5e4e241c99c93786eeddcd93c5ec23dd563881: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/9d5e4e241c99c93786eeddcd93c5ec23dd563881 -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/9e016e2a52e879c9c6482303eea8eb7d92b4dd38: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/a09fd95888cb80e1dcea4cc9dbd7d76928909927: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/a09fd95888cb80e1dcea4cc9dbd7d76928909927 -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/abb6d63b8f739c45c3c44f1772b88338e9b5e7a3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/abb6d63b8f739c45c3c44f1772b88338e9b5e7a3 -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_corpus/b67f23988e8274fcf6150a18dacb5ab3db49520d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile-shell/mosh/1105d481bb9143dad43adf768f58da7b029fd39c/src/fuzz/terminal_parser_corpus/b67f23988e8274fcf6150a18dacb5ab3db49520d -------------------------------------------------------------------------------- /src/fuzz/terminal_parser_fuzzer.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "src/terminal/parser.h" 5 | 6 | extern "C" int LLVMFuzzerTestOneInput( const uint8_t* data, size_t size ) 7 | { 8 | Parser::UTF8Parser parser; 9 | Parser::Actions result; 10 | 11 | for ( size_t i = 0; i < size; i++ ) { 12 | parser.input( data[i], result ); 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /src/include/Makefile.am: -------------------------------------------------------------------------------- 1 | BUILT_SOURCES = version.h 2 | nodist_INCLUDES = version.h 3 | 4 | clean-local: 5 | @rm -rf version.h 6 | 7 | version.h: ../../VERSION.stamp 8 | @test -s $< 9 | @printf '#define BUILD_VERSION "%s"\n' "$$(cat $<)" > $@.new 10 | @set -e; if ! diff -q $@ $@.new > /dev/null 2>&1; then \ 11 | mv -f $@.new $@; \ 12 | fi 13 | @rm -f $@.new 14 | 15 | -------------------------------------------------------------------------------- /src/network/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/ $(protobuf_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshnetwork.a 5 | 6 | libmoshnetwork_a_SOURCES = network.cc network.h networktransport-impl.h networktransport.h transportfragment.cc transportfragment.h transportsender-impl.h transportsender.h transportstate.h compressor.cc compressor.h 7 | -------------------------------------------------------------------------------- /src/network/compressor.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | 35 | #include "compressor.h" 36 | #include "src/util/dos_assert.h" 37 | 38 | using namespace Network; 39 | 40 | std::string Compressor::compress_str( const std::string& input ) 41 | { 42 | long unsigned int len = BUFFER_SIZE; 43 | dos_assert( Z_OK 44 | == compress( buffer, &len, reinterpret_cast( input.data() ), input.size() ) ); 45 | return std::string( reinterpret_cast( buffer ), len ); 46 | } 47 | 48 | std::string Compressor::uncompress_str( const std::string& input ) 49 | { 50 | long unsigned int len = BUFFER_SIZE; 51 | dos_assert( Z_OK 52 | == uncompress( buffer, &len, reinterpret_cast( input.data() ), input.size() ) ); 53 | return std::string( reinterpret_cast( buffer ), len ); 54 | } 55 | 56 | /* construct on first use */ 57 | Compressor& Network::get_compressor( void ) 58 | { 59 | static Compressor the_compressor; 60 | return the_compressor; 61 | } 62 | -------------------------------------------------------------------------------- /src/network/compressor.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef COMPRESSOR_H 34 | #define COMPRESSOR_H 35 | 36 | #include 37 | 38 | namespace Network { 39 | class Compressor 40 | { 41 | private: 42 | static const int BUFFER_SIZE = 2048 * 2048; /* effective limit on terminal size */ 43 | 44 | unsigned char buffer[BUFFER_SIZE]; 45 | 46 | public: 47 | Compressor() : buffer() {} 48 | ~Compressor() {} 49 | 50 | std::string compress_str( const std::string& input ); 51 | std::string uncompress_str( const std::string& input ); 52 | 53 | /* unused */ 54 | Compressor( const Compressor& ); 55 | Compressor& operator=( const Compressor& ); 56 | }; 57 | 58 | Compressor& get_compressor( void ); 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/network/transportfragment.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TRANSPORT_FRAGMENT_HPP 34 | #define TRANSPORT_FRAGMENT_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "src/protobufs/transportinstruction.pb.h" 41 | 42 | namespace Network { 43 | using namespace TransportBuffers; 44 | 45 | class Fragment 46 | { 47 | public: 48 | static const size_t frag_header_len = sizeof( uint64_t ) + sizeof( uint16_t ); 49 | 50 | uint64_t id; 51 | uint16_t fragment_num; 52 | bool final; 53 | 54 | bool initialized; 55 | 56 | std::string contents; 57 | 58 | Fragment() : id( -1 ), fragment_num( -1 ), final( false ), initialized( false ), contents() {} 59 | 60 | Fragment( uint64_t s_id, uint16_t s_fragment_num, bool s_final, const std::string& s_contents ) 61 | : id( s_id ), fragment_num( s_fragment_num ), final( s_final ), initialized( true ), contents( s_contents ) 62 | {} 63 | 64 | Fragment( const std::string& x ); 65 | 66 | std::string tostring( void ); 67 | 68 | bool operator==( const Fragment& x ) const; 69 | }; 70 | 71 | class FragmentAssembly 72 | { 73 | private: 74 | std::vector fragments; 75 | uint64_t current_id; 76 | int fragments_arrived, fragments_total; 77 | 78 | public: 79 | FragmentAssembly() : fragments(), current_id( -1 ), fragments_arrived( 0 ), fragments_total( -1 ) {} 80 | bool add_fragment( Fragment& inst ); 81 | Instruction get_assembly( void ); 82 | }; 83 | 84 | class Fragmenter 85 | { 86 | private: 87 | uint64_t next_instruction_id; 88 | Instruction last_instruction; 89 | size_t last_MTU; 90 | 91 | public: 92 | Fragmenter() : next_instruction_id( 0 ), last_instruction(), last_MTU( -1 ) 93 | { 94 | last_instruction.set_old_num( -1 ); 95 | last_instruction.set_new_num( -1 ); 96 | } 97 | std::vector make_fragments( const Instruction& inst, size_t MTU ); 98 | uint64_t last_ack_sent( void ) const { return last_instruction.ack_num(); } 99 | }; 100 | 101 | } 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/network/transportstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TRANSPORT_STATE_HPP 34 | #define TRANSPORT_STATE_HPP 35 | 36 | namespace Network { 37 | template 38 | class TimestampedState 39 | { 40 | public: 41 | uint64_t timestamp; 42 | uint64_t num; 43 | State state; 44 | 45 | TimestampedState( uint64_t s_timestamp, uint64_t s_num, const State& s_state ) 46 | : timestamp( s_timestamp ), num( s_num ), state( s_state ) 47 | {} 48 | }; 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/protobufs/Makefile.am: -------------------------------------------------------------------------------- 1 | source = userinput.proto hostinput.proto transportinstruction.proto 2 | 3 | AM_CPPFLAGS = $(protobuf_CFLAGS) 4 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) -Wno-error 5 | 6 | SUFFIXES = .proto .pb.cc 7 | 8 | .proto.pb.cc: 9 | $(AM_V_GEN)$(PROTOC) --cpp_out=. -I$(srcdir) $< 10 | 11 | noinst_LIBRARIES = libmoshprotos.a 12 | 13 | libmoshprotos_a_SOURCES = $(source) 14 | nodist_libmoshprotos_a_SOURCES = $(source:.proto=.pb.cc) $(source:.proto=.pb.h) 15 | 16 | BUILT_SOURCES = $(source:.proto=.pb.cc) 17 | CLEANFILES = $(source:.proto=.pb.cc) $(source:.proto=.pb.h) 18 | -------------------------------------------------------------------------------- /src/protobufs/hostinput.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option optimize_for = LITE_RUNTIME; 4 | 5 | package HostBuffers; 6 | 7 | message HostMessage { 8 | repeated Instruction instruction = 1; 9 | } 10 | 11 | message Instruction { 12 | extensions 2 to max; 13 | } 14 | 15 | message HostBytes { 16 | optional bytes hoststring = 4; 17 | } 18 | 19 | message ResizeMessage { 20 | optional int32 width = 5; 21 | optional int32 height = 6; 22 | } 23 | 24 | message EchoAck { 25 | optional uint64 echo_ack_num = 8; 26 | } 27 | 28 | extend Instruction { 29 | optional HostBytes hostbytes = 2; 30 | optional ResizeMessage resize = 3; 31 | optional EchoAck echoack = 7; 32 | } 33 | -------------------------------------------------------------------------------- /src/protobufs/transportinstruction.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option optimize_for = LITE_RUNTIME; 4 | 5 | package TransportBuffers; 6 | 7 | message Instruction { 8 | optional uint32 protocol_version = 1; 9 | 10 | optional uint64 old_num = 2; 11 | optional uint64 new_num = 3; 12 | optional uint64 ack_num = 4; 13 | optional uint64 throwaway_num = 5; 14 | 15 | optional bytes diff = 6; 16 | 17 | optional bytes chaff = 7; 18 | } 19 | -------------------------------------------------------------------------------- /src/protobufs/userinput.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option optimize_for = LITE_RUNTIME; 4 | 5 | package ClientBuffers; 6 | 7 | message UserMessage { 8 | repeated Instruction instruction = 1; 9 | } 10 | 11 | message Instruction { 12 | extensions 2 to max; 13 | } 14 | 15 | message Keystroke { 16 | optional bytes keys = 4; 17 | } 18 | 19 | message ResizeMessage { 20 | optional int32 width = 5; 21 | optional int32 height = 6; 22 | } 23 | 24 | extend Instruction { 25 | optional Keystroke keystroke = 2; 26 | optional ResizeMessage resize = 3; 27 | } 28 | -------------------------------------------------------------------------------- /src/statesync/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/ $(protobuf_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshstatesync.a 5 | 6 | libmoshstatesync_a_SOURCES = completeterminal.cc completeterminal.h user.cc user.h 7 | -------------------------------------------------------------------------------- /src/statesync/completeterminal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef COMPLETE_TERMINAL_HPP 34 | #define COMPLETE_TERMINAL_HPP 35 | 36 | #include 37 | #include 38 | 39 | #include "src/terminal/parser.h" 40 | #include "src/terminal/terminal.h" 41 | 42 | /* This class represents the complete terminal -- a UTF8Parser feeding Actions to an Emulator. */ 43 | 44 | namespace Terminal { 45 | class Complete 46 | { 47 | private: 48 | Parser::UTF8Parser parser; 49 | Terminal::Emulator terminal; 50 | Terminal::Display display; 51 | 52 | // Only used locally by act(), but kept here as a performance optimization, 53 | // to avoid construction/destruction. It must always be empty 54 | // outside calls to act() to keep horrible things from happening. 55 | Parser::Actions actions; 56 | 57 | using input_history_type = std::list>; 58 | input_history_type input_history; 59 | uint64_t echo_ack; 60 | 61 | static const int ECHO_TIMEOUT = 50; /* for late ack */ 62 | 63 | public: 64 | Complete( size_t width, size_t height ) 65 | : parser(), terminal( width, height ), display( false ), actions(), input_history(), echo_ack( 0 ) 66 | {} 67 | 68 | std::string act( const std::string& str ); 69 | std::string act( const Parser::Action& act ); 70 | 71 | const Framebuffer& get_fb( void ) const { return terminal.get_fb(); } 72 | void reset_input( void ) { parser.reset_input(); } 73 | uint64_t get_echo_ack( void ) const { return echo_ack; } 74 | bool set_echo_ack( uint64_t now ); 75 | void register_input_frame( uint64_t n, uint64_t now ); 76 | int wait_time( uint64_t now ) const; 77 | 78 | /* interface for Network::Transport */ 79 | void subtract( const Complete* ) const {} 80 | std::string diff_from( const Complete& existing ) const; 81 | std::string init_diff( void ) const; 82 | void apply_string( const std::string& diff ); 83 | bool operator==( const Complete& x ) const; 84 | 85 | bool compare( const Complete& other ) const; 86 | }; 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/statesync/user.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef USER_HPP 34 | #define USER_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include "src/terminal/parseraction.h" 42 | 43 | namespace Network { 44 | enum UserEventType 45 | { 46 | UserByteType = 0, 47 | ResizeType = 1 48 | }; 49 | 50 | class UserEvent 51 | { 52 | public: 53 | UserEventType type; 54 | Parser::UserByte userbyte; 55 | Parser::Resize resize; 56 | 57 | UserEvent( const Parser::UserByte& s_userbyte ) : type( UserByteType ), userbyte( s_userbyte ), resize( -1, -1 ) 58 | {} 59 | UserEvent( const Parser::Resize& s_resize ) : type( ResizeType ), userbyte( 0 ), resize( s_resize ) {} 60 | 61 | private: 62 | UserEvent(); 63 | 64 | public: 65 | bool operator==( const UserEvent& x ) const 66 | { 67 | return ( type == x.type ) && ( userbyte == x.userbyte ) && ( resize == x.resize ); 68 | } 69 | }; 70 | 71 | class UserStream 72 | { 73 | private: 74 | std::deque actions; 75 | 76 | public: 77 | UserStream() : actions() {} 78 | 79 | void push_back( const Parser::UserByte& s_userbyte ) { actions.push_back( UserEvent( s_userbyte ) ); } 80 | void push_back( const Parser::Resize& s_resize ) { actions.push_back( UserEvent( s_resize ) ); } 81 | 82 | bool empty( void ) const { return actions.empty(); } 83 | size_t size( void ) const { return actions.size(); } 84 | const Parser::Action& get_action( unsigned int i ) const; 85 | 86 | /* interface for Network::Transport */ 87 | void subtract( const UserStream* prefix ); 88 | std::string diff_from( const UserStream& existing ) const; 89 | std::string init_diff( void ) const { return diff_from( UserStream() ); }; 90 | void apply_string( const std::string& diff ); 91 | bool operator==( const UserStream& x ) const { return actions == x.actions; } 92 | 93 | bool compare( const UserStream& ) { return false; } 94 | }; 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/terminal/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/ $(TINFO_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshterminal.a 5 | 6 | libmoshterminal_a_SOURCES = parseraction.cc parseraction.h parser.cc parser.h parserstate.cc parserstatefamily.h parserstate.h parsertransition.h terminal.cc terminaldispatcher.cc terminaldispatcher.h terminaldisplay.cc terminaldisplayinit.cc terminaldisplay.h terminalframebuffer.cc terminalframebuffer.h terminalfunctions.cc terminal.h terminaluserinput.cc terminaluserinput.h 7 | -------------------------------------------------------------------------------- /src/terminal/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PARSER_HPP 34 | #define PARSER_HPP 35 | 36 | /* Based on Paul Williams's parser, 37 | http://www.vt100.net/emu/dec_ansi_parser */ 38 | 39 | #include 40 | #include 41 | 42 | #include "parserstate.h" 43 | #include "parserstatefamily.h" 44 | #include "parsertransition.h" 45 | #include "src/terminal/parseraction.h" 46 | 47 | namespace Parser { 48 | extern const StateFamily family; 49 | 50 | class Parser 51 | { 52 | private: 53 | State const* state; 54 | 55 | public: 56 | Parser() : state( &family.s_Ground ) {} 57 | 58 | Parser( const Parser& other ); 59 | Parser& operator=( const Parser& ); 60 | ~Parser() {} 61 | 62 | void input( wchar_t ch, Actions& actions ); 63 | 64 | void reset_input( void ) { state = &family.s_Ground; } 65 | }; 66 | 67 | static const size_t BUF_SIZE = 8; 68 | 69 | class UTF8Parser 70 | { 71 | private: 72 | Parser parser; 73 | 74 | char buf[BUF_SIZE]; 75 | size_t buf_len; 76 | 77 | public: 78 | UTF8Parser(); 79 | 80 | void input( char c, Actions& actions ); 81 | 82 | void reset_input( void ) 83 | { 84 | parser.reset_input(); 85 | buf[0] = '\0'; 86 | buf_len = 0; 87 | } 88 | }; 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/terminal/parseraction.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | #include "src/terminal/parseraction.h" 37 | #include "src/terminal/terminal.h" 38 | 39 | using namespace Parser; 40 | 41 | void Print::act_on_terminal( Terminal::Emulator* emu ) const 42 | { 43 | emu->print( this ); 44 | } 45 | 46 | void Execute::act_on_terminal( Terminal::Emulator* emu ) const 47 | { 48 | emu->execute( this ); 49 | } 50 | 51 | void Clear::act_on_terminal( Terminal::Emulator* emu ) const 52 | { 53 | emu->dispatch.clear( this ); 54 | } 55 | 56 | void Param::act_on_terminal( Terminal::Emulator* emu ) const 57 | { 58 | emu->dispatch.newparamchar( this ); 59 | } 60 | 61 | void Collect::act_on_terminal( Terminal::Emulator* emu ) const 62 | { 63 | emu->dispatch.collect( this ); 64 | } 65 | 66 | void CSI_Dispatch::act_on_terminal( Terminal::Emulator* emu ) const 67 | { 68 | emu->CSI_dispatch( this ); 69 | } 70 | 71 | void Esc_Dispatch::act_on_terminal( Terminal::Emulator* emu ) const 72 | { 73 | emu->Esc_dispatch( this ); 74 | } 75 | 76 | void OSC_Put::act_on_terminal( Terminal::Emulator* emu ) const 77 | { 78 | emu->dispatch.OSC_put( this ); 79 | } 80 | 81 | void OSC_Start::act_on_terminal( Terminal::Emulator* emu ) const 82 | { 83 | emu->dispatch.OSC_start( this ); 84 | } 85 | 86 | void OSC_End::act_on_terminal( Terminal::Emulator* emu ) const 87 | { 88 | emu->OSC_end( this ); 89 | } 90 | 91 | void UserByte::act_on_terminal( Terminal::Emulator* emu ) const 92 | { 93 | emu->dispatch.terminal_to_host.append( emu->user.input( this, emu->fb.ds.application_mode_cursor_keys ) ); 94 | } 95 | 96 | void Resize::act_on_terminal( Terminal::Emulator* emu ) const 97 | { 98 | emu->resize( width, height ); 99 | } 100 | -------------------------------------------------------------------------------- /src/terminal/parserstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PARSERSTATE_HPP 34 | #define PARSERSTATE_HPP 35 | 36 | #include "parsertransition.h" 37 | 38 | namespace Parser { 39 | class StateFamily; 40 | 41 | class State 42 | { 43 | protected: 44 | virtual Transition input_state_rule( wchar_t ch ) const = 0; 45 | StateFamily* family; 46 | 47 | private: 48 | Transition anywhere_rule( wchar_t ch ) const; 49 | 50 | public: 51 | void setfamily( StateFamily* s_family ) { family = s_family; } 52 | Transition input( wchar_t ch ) const; 53 | virtual ActionPointer enter( void ) const { return std::make_shared(); } 54 | virtual ActionPointer exit( void ) const { return std::make_shared(); } 55 | 56 | State() : family( NULL ) {}; 57 | virtual ~State() {}; 58 | 59 | State( const State& ); 60 | State& operator=( const State& ); 61 | }; 62 | 63 | class Ground : public State 64 | { 65 | Transition input_state_rule( wchar_t ch ) const; 66 | }; 67 | 68 | class Escape : public State 69 | { 70 | ActionPointer enter( void ) const; 71 | Transition input_state_rule( wchar_t ch ) const; 72 | }; 73 | 74 | class Escape_Intermediate : public State 75 | { 76 | Transition input_state_rule( wchar_t ch ) const; 77 | }; 78 | 79 | class CSI_Entry : public State 80 | { 81 | ActionPointer enter( void ) const; 82 | Transition input_state_rule( wchar_t ch ) const; 83 | }; 84 | class CSI_Param : public State 85 | { 86 | Transition input_state_rule( wchar_t ch ) const; 87 | }; 88 | class CSI_Intermediate : public State 89 | { 90 | Transition input_state_rule( wchar_t ch ) const; 91 | }; 92 | class CSI_Ignore : public State 93 | { 94 | Transition input_state_rule( wchar_t ch ) const; 95 | }; 96 | 97 | class DCS_Entry : public State 98 | { 99 | ActionPointer enter( void ) const; 100 | Transition input_state_rule( wchar_t ch ) const; 101 | }; 102 | class DCS_Param : public State 103 | { 104 | Transition input_state_rule( wchar_t ch ) const; 105 | }; 106 | class DCS_Intermediate : public State 107 | { 108 | Transition input_state_rule( wchar_t ch ) const; 109 | }; 110 | class DCS_Passthrough : public State 111 | { 112 | ActionPointer enter( void ) const; 113 | Transition input_state_rule( wchar_t ch ) const; 114 | ActionPointer exit( void ) const; 115 | }; 116 | class DCS_Ignore : public State 117 | { 118 | Transition input_state_rule( wchar_t ch ) const; 119 | }; 120 | 121 | class OSC_String : public State 122 | { 123 | ActionPointer enter( void ) const; 124 | Transition input_state_rule( wchar_t ch ) const; 125 | ActionPointer exit( void ) const; 126 | }; 127 | class SOS_PM_APC_String : public State 128 | { 129 | Transition input_state_rule( wchar_t ch ) const; 130 | }; 131 | } 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /src/terminal/parserstatefamily.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PARSERSTATEFAMILY_HPP 34 | #define PARSERSTATEFAMILY_HPP 35 | 36 | #include "parserstate.h" 37 | 38 | namespace Parser { 39 | class StateFamily 40 | { 41 | public: 42 | Ground s_Ground; 43 | 44 | Escape s_Escape; 45 | Escape_Intermediate s_Escape_Intermediate; 46 | 47 | CSI_Entry s_CSI_Entry; 48 | CSI_Param s_CSI_Param; 49 | CSI_Intermediate s_CSI_Intermediate; 50 | CSI_Ignore s_CSI_Ignore; 51 | 52 | DCS_Entry s_DCS_Entry; 53 | DCS_Param s_DCS_Param; 54 | DCS_Intermediate s_DCS_Intermediate; 55 | DCS_Passthrough s_DCS_Passthrough; 56 | DCS_Ignore s_DCS_Ignore; 57 | 58 | OSC_String s_OSC_String; 59 | SOS_PM_APC_String s_SOS_PM_APC_String; 60 | 61 | StateFamily() 62 | : s_Ground(), s_Escape(), s_Escape_Intermediate(), s_CSI_Entry(), s_CSI_Param(), s_CSI_Intermediate(), 63 | s_CSI_Ignore(), s_DCS_Entry(), s_DCS_Param(), s_DCS_Intermediate(), s_DCS_Passthrough(), s_DCS_Ignore(), 64 | s_OSC_String(), s_SOS_PM_APC_String() 65 | { 66 | s_Ground.setfamily( this ); 67 | s_Escape.setfamily( this ); 68 | s_Escape_Intermediate.setfamily( this ); 69 | s_CSI_Entry.setfamily( this ); 70 | s_CSI_Param.setfamily( this ); 71 | s_CSI_Intermediate.setfamily( this ); 72 | s_CSI_Ignore.setfamily( this ); 73 | s_DCS_Entry.setfamily( this ); 74 | s_DCS_Param.setfamily( this ); 75 | s_DCS_Intermediate.setfamily( this ); 76 | s_DCS_Passthrough.setfamily( this ); 77 | s_DCS_Ignore.setfamily( this ); 78 | s_OSC_String.setfamily( this ); 79 | s_SOS_PM_APC_String.setfamily( this ); 80 | } 81 | }; 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/terminal/parsertransition.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PARSERTRANSITION_HPP 34 | #define PARSERTRANSITION_HPP 35 | 36 | #include 37 | 38 | #include "src/terminal/parseraction.h" 39 | 40 | namespace Parser { 41 | class State; 42 | 43 | class Transition 44 | { 45 | public: 46 | // Transition is only a courier for an Action; it should 47 | // never create/delete one on its own. 48 | ActionPointer action; 49 | State* next_state; 50 | 51 | Transition( const Transition& x ) : action( x.action ), next_state( x.next_state ) {} 52 | Transition& operator=( const Transition& t ) 53 | { 54 | action = t.action; 55 | next_state = t.next_state; 56 | 57 | return *this; 58 | } 59 | Transition( ActionPointer s_action = std::make_shared(), State* s_next_state = NULL ) 60 | : action( s_action ), next_state( s_next_state ) 61 | {} 62 | 63 | // This is only ever used in the 1-argument form; 64 | // we use this instead of an initializer to 65 | // tell Coverity the object never owns *action. 66 | Transition( State* s_next_state, ActionPointer s_action = std::make_shared() ) 67 | : action( s_action ), next_state( s_next_state ) 68 | {} 69 | }; 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/terminal/terminal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TERMINAL_CPP 34 | #define TERMINAL_CPP 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include "src/terminal/parseraction.h" 42 | #include "src/terminal/terminalframebuffer.h" 43 | #include "terminaldispatcher.h" 44 | #include "terminaldisplay.h" 45 | #include "terminaluserinput.h" 46 | 47 | namespace Terminal { 48 | class Emulator 49 | { 50 | friend void Parser::Print::act_on_terminal( Emulator* ) const; 51 | friend void Parser::Execute::act_on_terminal( Emulator* ) const; 52 | friend void Parser::Clear::act_on_terminal( Emulator* ) const; 53 | friend void Parser::Param::act_on_terminal( Emulator* ) const; 54 | friend void Parser::Collect::act_on_terminal( Emulator* ) const; 55 | friend void Parser::CSI_Dispatch::act_on_terminal( Emulator* ) const; 56 | friend void Parser::Esc_Dispatch::act_on_terminal( Emulator* ) const; 57 | friend void Parser::OSC_Start::act_on_terminal( Emulator* ) const; 58 | friend void Parser::OSC_Put::act_on_terminal( Emulator* ) const; 59 | friend void Parser::OSC_End::act_on_terminal( Emulator* ) const; 60 | 61 | friend void Parser::UserByte::act_on_terminal( Emulator* ) const; 62 | friend void Parser::Resize::act_on_terminal( Emulator* ) const; 63 | 64 | private: 65 | Framebuffer fb; 66 | Dispatcher dispatch; 67 | UserInput user; 68 | 69 | /* action methods */ 70 | void print( const Parser::Print* act ); 71 | void execute( const Parser::Execute* act ); 72 | void CSI_dispatch( const Parser::CSI_Dispatch* act ); 73 | void Esc_dispatch( const Parser::Esc_Dispatch* act ); 74 | void OSC_end( const Parser::OSC_End* act ); 75 | void resize( size_t s_width, size_t s_height ); 76 | 77 | public: 78 | Emulator( size_t s_width, size_t s_height ); 79 | 80 | std::string read_octets_to_host( void ); 81 | 82 | const Framebuffer& get_fb( void ) const { return fb; } 83 | 84 | bool operator==( Emulator const& x ) const; 85 | }; 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/terminal/terminaldispatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TERMINALDISPATCHER_HPP 34 | #define TERMINALDISPATCHER_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | namespace Parser { 41 | class Action; 42 | class Param; 43 | class Collect; 44 | class Clear; 45 | class Esc_Dispatch; 46 | class CSI_Dispatch; 47 | class Execute; 48 | class OSC_Start; 49 | class OSC_Put; 50 | class OSC_End; 51 | } 52 | 53 | namespace Terminal { 54 | class Framebuffer; 55 | class Dispatcher; 56 | 57 | enum Function_Type 58 | { 59 | ESCAPE, 60 | CSI, 61 | CONTROL 62 | }; 63 | 64 | class Function 65 | { 66 | public: 67 | Function() : function( NULL ), clears_wrap_state( true ) {} 68 | Function( Function_Type type, 69 | const std::string& dispatch_chars, 70 | void ( *s_function )( Framebuffer*, Dispatcher* ), 71 | bool s_clears_wrap_state = true ); 72 | void ( *function )( Framebuffer*, Dispatcher* ); 73 | bool clears_wrap_state; 74 | }; 75 | 76 | using dispatch_map_t = std::map; 77 | 78 | class DispatchRegistry 79 | { 80 | public: 81 | dispatch_map_t escape; 82 | dispatch_map_t CSI; 83 | dispatch_map_t control; 84 | 85 | DispatchRegistry() : escape(), CSI(), control() {} 86 | }; 87 | 88 | DispatchRegistry& get_global_dispatch_registry( void ); 89 | 90 | class Dispatcher 91 | { 92 | private: 93 | std::string params; 94 | std::vector parsed_params; 95 | bool parsed; 96 | 97 | std::string dispatch_chars; 98 | std::vector OSC_string; /* only used to set the window title */ 99 | 100 | void parse_params( void ); 101 | 102 | public: 103 | static const int PARAM_MAX = 65535; 104 | /* prevent evil escape sequences from causing long loops */ 105 | 106 | std::string terminal_to_host; /* this is the reply string */ 107 | 108 | Dispatcher(); 109 | int getparam( size_t N, int defaultval ); 110 | int param_count( void ); 111 | 112 | void newparamchar( const Parser::Param* act ); 113 | void collect( const Parser::Collect* act ); 114 | void clear( const Parser::Clear* act ); 115 | 116 | std::string str( void ); 117 | 118 | void dispatch( Function_Type type, const Parser::Action* act, Framebuffer* fb ); 119 | std::string get_dispatch_chars( void ) const { return dispatch_chars; } 120 | std::vector get_OSC_string( void ) const { return OSC_string; } 121 | 122 | void OSC_put( const Parser::OSC_Put* act ); 123 | void OSC_start( const Parser::OSC_Start* act ); 124 | void OSC_dispatch( const Parser::OSC_End* act, Framebuffer* fb ); 125 | 126 | bool operator==( const Dispatcher& x ) const; 127 | }; 128 | } 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /src/terminal/terminaldisplay.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TERMINALDISPLAY_HPP 34 | #define TERMINALDISPLAY_HPP 35 | 36 | #include "src/terminal/terminalframebuffer.h" 37 | 38 | namespace Terminal { 39 | /* variables used within a new_frame */ 40 | class FrameState 41 | { 42 | public: 43 | std::string str; 44 | 45 | int cursor_x, cursor_y; 46 | Renditions current_rendition; 47 | bool cursor_visible; 48 | 49 | const Framebuffer& last_frame; 50 | 51 | FrameState( const Framebuffer& s_last ); 52 | 53 | void append( char c ) { str.append( 1, c ); } 54 | void append( size_t s, char c ) { str.append( s, c ); } 55 | void append( wchar_t wc ) { Cell::append_to_str( str, wc ); } 56 | void append( const char* s ) { str.append( s ); } 57 | void append_string( const std::string& append ) { str.append( append ); } 58 | 59 | void append_cell( const Cell& cell ) { cell.print_grapheme( str ); } 60 | void append_silent_move( int y, int x ); 61 | void append_move( int y, int x ); 62 | void update_rendition( const Renditions& r, bool force = false ); 63 | }; 64 | 65 | class Display 66 | { 67 | private: 68 | bool has_ech; /* erase character is part of vt200 but not supported by tmux 69 | (or by "screen" terminfo entry, which is what tmux advertises) */ 70 | 71 | bool has_bce; /* erases result in cell filled with background color */ 72 | 73 | bool has_title; /* supports window title and icon name */ 74 | 75 | const char *smcup, *rmcup; /* enter and exit alternate screen mode */ 76 | 77 | bool put_row( bool initialized, 78 | FrameState& frame, 79 | const Framebuffer& f, 80 | int frame_y, 81 | const Row& old_row, 82 | bool wrap ) const; 83 | 84 | public: 85 | std::string open() const; 86 | std::string close() const; 87 | 88 | std::string new_frame( bool initialized, const Framebuffer& last, const Framebuffer& f ) const; 89 | 90 | Display( bool use_environment ); 91 | }; 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/terminal/terminaluserinput.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | 35 | #include "terminaluserinput.h" 36 | 37 | using namespace Terminal; 38 | 39 | std::string UserInput::input( const Parser::UserByte* act, bool application_mode_cursor_keys ) 40 | { 41 | /* The user will always be in application mode. If stm is not in 42 | application mode, convert user's cursor control function to an 43 | ANSI cursor control sequence */ 44 | 45 | /* We need to look ahead one byte in the SS3 state to see if 46 | the next byte will be A, B, C, or D (cursor control keys). */ 47 | 48 | /* This doesn't handle the 8-bit SS3 C1 control, which would be 49 | two octets in UTF-8. Fortunately nobody seems to send this. */ 50 | 51 | switch ( state ) { 52 | case Ground: 53 | if ( act->c == 0x1b ) { /* ESC */ 54 | state = ESC; 55 | } 56 | return std::string( &act->c, 1 ); 57 | 58 | case ESC: 59 | if ( act->c == 'O' ) { /* ESC O = 7-bit SS3 */ 60 | state = SS3; 61 | return std::string(); 62 | } 63 | state = Ground; 64 | return std::string( &act->c, 1 ); 65 | 66 | case SS3: 67 | state = Ground; 68 | if ( ( !application_mode_cursor_keys ) && ( act->c >= 'A' ) && ( act->c <= 'D' ) ) { 69 | char translated_cursor[2] = { '[', act->c }; 70 | return std::string( translated_cursor, 2 ); 71 | } else { 72 | char original_cursor[2] = { 'O', act->c }; 73 | return std::string( original_cursor, 2 ); 74 | } 75 | 76 | default: 77 | assert( !"unexpected state" ); 78 | state = Ground; 79 | return std::string(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/terminal/terminaluserinput.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TERMINALUSERINPUT_HPP 34 | #define TERMINALUSERINPUT_HPP 35 | 36 | #include "src/terminal/parseraction.h" 37 | #include 38 | 39 | namespace Terminal { 40 | class UserInput 41 | { 42 | public: 43 | enum UserInputState 44 | { 45 | Ground, 46 | ESC, 47 | SS3 48 | }; 49 | 50 | private: 51 | UserInputState state; 52 | 53 | public: 54 | UserInput() : state( Ground ) {} 55 | 56 | std::string input( const Parser::UserByte* act, bool application_mode_cursor_keys ); 57 | 58 | bool operator==( const UserInput& x ) const { return state == x.state; } 59 | }; 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/tests/.gitignore: -------------------------------------------------------------------------------- 1 | /base64 2 | /base64_vector.cc 3 | /ocb-aes 4 | /encrypt-decrypt 5 | /nonce-incr 6 | /inpty 7 | /is-utf8-locale 8 | /*.d/ 9 | *.log 10 | *.trs 11 | -------------------------------------------------------------------------------- /src/tests/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = \ 2 | hold-stdin print-exitstatus \ 3 | e2e-test e2e-test-server \ 4 | e2e-test-subrs \ 5 | mosh-client mosh-server \ 6 | local.test \ 7 | $(displaytests) \ 8 | emulation-attributes.test 9 | 10 | AM_CXXFLAGS = -I$(top_srcdir)/ $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 11 | AM_LDFLAGS = $(HARDEN_LDFLAGS) $(CODE_COVERAGE_LIBS) 12 | 13 | displaytests = \ 14 | e2e-success.test \ 15 | e2e-failure.test \ 16 | emulation-ascii-iso-8859.test \ 17 | emulation-80th-column.test \ 18 | emulation-attributes-vt100.test \ 19 | emulation-attributes-16color.test \ 20 | emulation-attributes-256color8.test \ 21 | emulation-attributes-256color248.test \ 22 | emulation-attributes-truecolor.test \ 23 | emulation-attributes-bce.test \ 24 | emulation-back-tab.test \ 25 | emulation-cursor-motion.test \ 26 | emulation-multiline-scroll.test \ 27 | emulation-scroll.test \ 28 | emulation-wrap-across-frames.test \ 29 | network-no-diff.test \ 30 | prediction-unicode.test \ 31 | pty-deadlock.test \ 32 | repeat.test \ 33 | repeat-with-input.test \ 34 | server-network-timeout.test \ 35 | server-signal-timeout.test \ 36 | window-resize.test \ 37 | unicode-combine-fallback-assert.test \ 38 | unicode-later-combining.test \ 39 | window-resize.test 40 | 41 | check_PROGRAMS = ocb-aes encrypt-decrypt base64 nonce-incr inpty is-utf8-locale 42 | TESTS = ocb-aes encrypt-decrypt base64 nonce-incr local.test $(displaytests) 43 | XFAIL_TESTS = \ 44 | e2e-failure.test \ 45 | emulation-attributes-256color8.test 46 | 47 | base64_vector.cc: $(srcdir)/genbase64.pl 48 | $(AM_V_GEN)echo '#include "base64_vector.h"' > base64_vector.cc || rm base64_vector.cc 49 | $(AM_V_GEN)perl $(srcdir)/genbase64.pl >> base64_vector.cc || rm base64_vector.cc 50 | 51 | ocb_aes_SOURCES = ocb-aes.cc test_utils.cc test_utils.h 52 | ocb_aes_CPPFLAGS = -I$(srcdir)/../crypto -I$(srcdir)/../util $(CRYPTO_CFLAGS) 53 | ocb_aes_LDADD = ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(CRYPTO_LIBS) 54 | 55 | encrypt_decrypt_SOURCES = encrypt-decrypt.cc test_utils.cc test_utils.h 56 | encrypt_decrypt_CPPFLAGS = -I$(srcdir)/../crypto -I$(srcdir)/../util 57 | encrypt_decrypt_LDADD = ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(CRYPTO_LIBS) 58 | 59 | base64_SOURCES = base64.cc base64_vector.cc base64_vector.h genbase64.pl 60 | base64_CPPFLAGS = $(ocb_aes_CPPFLAGS) 61 | base64_LDADD = $(ocb_aes_LDADD) 62 | 63 | nonce_incr_SOURCES = nonce-incr.cc 64 | nonce_incr_CPPFLAGS = -I$(srcdir)/../network -I$(srcdir)/../crypto -I$(srcdir)/../util $(CRYPTO_CFLAGS) 65 | nonce_incr_LDADD = ../network/libmoshnetwork.a ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(CRYPTO_LIBS) 66 | 67 | inpty_SOURCES = inpty.cc 68 | inpty_CPPFLAGS = -I$(srcdir)/../util 69 | inpty_LDADD = ../util/libmoshutil.a 70 | 71 | is_utf8_locale_SOURCES = is-utf8-locale.cc 72 | is_utf8_locale_CPPFLAGS = -I$(srcdir)/../util 73 | is_utf8_locale_LDADD = ../util/libmoshutil.a $(LIBUTIL) 74 | 75 | clean-local: clean-local-check 76 | .PHONY: clean-local-check 77 | clean-local-check: 78 | -for i in $(displaytests); do rm -rf $$i.d/; done 79 | 80 | CLEANFILES = base64_vector.cc 81 | -------------------------------------------------------------------------------- /src/tests/base64_vector.h: -------------------------------------------------------------------------------- 1 | struct base64_test_row 2 | { 3 | const unsigned char native[17]; 4 | const char encoded[25]; 5 | }; 6 | typedef base64_test_row* base64_test_vector; 7 | extern base64_test_row static_base64_vector[]; 8 | -------------------------------------------------------------------------------- /src/tests/e2e-failure.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # shellcheck source=e2e-test-subrs 4 | . "$(dirname "$0")/e2e-test-subrs" 5 | PATH=$PATH:.:$srcdir 6 | # Top-level wrapper. 7 | if [ $# -eq 0 ]; then 8 | e2e-test "$0" baseline variant different 9 | exit 10 | fi 11 | 12 | # OK, we have arguments, we're one of the test hooks. 13 | if [ $# -ne 1 ]; then 14 | fail "bad arguments %s\n" "$@" 15 | fi 16 | 17 | baseline() 18 | { 19 | printf "\033[H\033[J" 20 | } 21 | 22 | case $1 in 23 | baseline|variant) 24 | baseline;; 25 | *) 26 | fail "unknown test argument %s\n" "$1";; 27 | esac 28 | -------------------------------------------------------------------------------- /src/tests/e2e-success.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # shellcheck source=e2e-test-subrs 4 | . "$(dirname "$0")/e2e-test-subrs" 5 | PATH=$PATH:.:$srcdir 6 | # Top-level wrapper. 7 | if [ $# -eq 0 ]; then 8 | e2e-test "$0" baseline direct variant verify same 9 | exit 10 | fi 11 | 12 | # OK, we have arguments, we're one of the test hooks. 13 | if [ $# -ne 1 ]; then 14 | fail "bad arguments %s\n" "$@" 15 | fi 16 | 17 | baseline() 18 | { 19 | printf "\033[H\033[J" 20 | } 21 | 22 | case $1 in 23 | baseline|direct|variant) 24 | baseline;; 25 | *) 26 | fail "unknown test argument %s\n" "$1";; 27 | esac 28 | -------------------------------------------------------------------------------- /src/tests/e2e-test-server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Harness script for Mosh tests, server side. Runs test script and 5 | # then captures screen with `tmux capture-pane`. Captures exitstatus 6 | # of both and returns appropriate errors. 7 | # 8 | 9 | # If MOSH_E2E_WAIT is set, then the test will wait for another tmux 10 | # client to attach to the test session before starting, and will wait 11 | # for other tmux clients to detach before exiting. 12 | wait_for_clients() 13 | { 14 | if [ -z "$MOSH_E2E_WAIT" ]; then 15 | return 16 | fi 17 | expected=$1 18 | while true; do 19 | n=$(tmux list-clients -F . | wc -l) 20 | if [ $expected -eq 1 ]; then 21 | if [ $n -eq 1 ]; then 22 | return 23 | fi 24 | elif [ $n -ne 1 ]; then 25 | return 26 | fi 27 | sleep 1 28 | done 29 | } 30 | 31 | export MOSH_SERVER_PID=$PPID 32 | 33 | if [ $# -lt 2 ]; then 34 | printf "not enough args\n" >&2 35 | exit 99 36 | fi 37 | testname=$1 38 | shift 39 | rm -f "$testname.capture" "$testname.exitstatus" 40 | trap ":" TERM HUP QUIT # If the session closes on us, let the test we're running drive. 41 | on_exit() { 42 | rv=$? 43 | echo $rv > "$testname.exitstatus" 44 | exit $rv 45 | } 46 | trap on_exit EXIT 47 | # check for tmux 48 | if [ -z "$TMUX_PANE" ]; then 49 | printf "not running under tmux\n" >&2 50 | exit 99 51 | fi 52 | wait_for_clients 2 53 | # run harnessed command 54 | eval "$@" 55 | testret=$? 56 | # Capture mosh-server runtime if possible. 57 | runtime=$(ps -o time= $PPID 2>/dev/null) 58 | if [ $? -ne 0 ]; then # Cygwin... 59 | runtime=- 60 | fi 61 | # Wait for tmux client screen to become up to date. 62 | sleep 1 63 | printf "@@@ server complete @@@" >&2 64 | wait_for_clients 1 65 | i=0 66 | while [ $i -lt 60 ]; do 67 | if grep -q "@@@ server complete @@@" "$testname.tmux.log"; then 68 | break 69 | fi 70 | i=$((i+1)) 71 | sleep 1 72 | done 73 | if [ $i -ge 60 ]; then 74 | printf "wait for tmux client update failed, erroring test\n" >&2 75 | exit 99 76 | fi 77 | # capture screen 78 | if ! tmux capture-pane -et "$TMUX_PANE"; then 79 | printf "tmux capture-pane failed, erroring test\n" >&2 80 | exit 99 81 | fi 82 | if ! tmux save-buffer "$testname.capture"; then 83 | printf "tmux save-buffer failed, erroring test\n" >&2 84 | exit 99 85 | fi 86 | # Dump runtime into tmux log. 87 | printf "@@@ runtime %s @@@\n" "$runtime" 88 | # return useful exitstatus from harnessed command 89 | if [ $testret -ne 0 ]; then 90 | exit 1 91 | fi 92 | exit 0 93 | -------------------------------------------------------------------------------- /src/tests/e2e-test-subrs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This is a library of subroutines mostly intended for test scripts. 5 | # 6 | 7 | fail() 8 | { 9 | printf "$@" 2>&1 10 | exit 99 11 | } 12 | 13 | skip() 14 | { 15 | printf "$@" 2>&1 16 | exit 77 17 | } 18 | 19 | sleepf() 20 | { 21 | (sleep .1 || sleep 1) > /dev/null 2>&1 22 | } 23 | 24 | seq_function() 25 | { 26 | if [ $# -lt 1 ] || [ $# -gt 3 ]; then 27 | echo "bad args" >&2 28 | fi 29 | first=$1 30 | incr=1 31 | last=0 32 | case $# in 33 | 3) 34 | incr=$2 35 | last=$3 36 | ;; 37 | 2) 38 | last=$2 39 | ;; 40 | 1) 41 | ;; 42 | esac 43 | while :; do 44 | printf '%d\n' "$first" 45 | first=$(( first + incr )) 46 | if [ "$first" -gt "$last" ]; then 47 | break 48 | fi 49 | done 50 | } 51 | 52 | if ! seq 1 > /dev/null 2>&1; then 53 | seq() 54 | { 55 | seq_function "$@" 56 | } 57 | fi 58 | 59 | chr() 60 | { 61 | printf '%b' "\\0$(printf %03o "$1")" 62 | } 63 | 64 | # If the locale is not set to a UTF-8 locale, set it to en_US.UTF-8 65 | # or C.UTF-8. 66 | set_locale() 67 | { 68 | # Test for a usable locale. 69 | if ./is-utf8-locale 2> /dev/null; then 70 | return 0 71 | fi 72 | # Attempt to find/set a usable locale. 73 | unset LANG LC_CTYPE LC_COLLATE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LC_ALL 74 | for i in en_US.UTF-8 en_US.utf8 C.UTF-8; do 75 | if env LC_ALL=$i ./is-utf8-locale 2> /dev/null; then 76 | export LC_ALL=$i 77 | return 0 78 | fi 79 | done 80 | # Fail. 81 | return 1 82 | } 83 | 84 | # Given two versions, return success if the first version is less than 85 | # or equal to the second version. 86 | versionlte() 87 | { 88 | [ "$1" = "$(printf "$1\n$2\n" | sort -V | head -n1)" ] 89 | } 90 | versionlt() { 91 | if [ "$1" = "$2" ]; then 92 | return 1 93 | fi 94 | versionlte "$1" "$2" 95 | } 96 | 97 | # Tmux check. 98 | tmux_check() 99 | { 100 | need_major="$1"; shift 101 | need_minor="$1"; shift 102 | # OpenBSD tmux does not have '-V'. 103 | if [ "$(uname -s)" = "OpenBSD" ]; then 104 | openbsd_major="$(uname -r)" 105 | openbsd_major="${openbsd_major%%.*}" 106 | if [ "${openbsd_major}" -ge 6 ]; then 107 | return 0 108 | fi 109 | fi 110 | version=$(tmux -V) 111 | if [ $? != 0 ]; then 112 | error "tmux unavailable\n" 113 | return 1 114 | fi 115 | if [ "$version" = "tmux master" ]; then 116 | return 0 117 | fi 118 | version=${version##tmux } 119 | 120 | if versionlt "$version" "$need_major.$need_minor"; then 121 | printf "tmux version %s too old\n" "$version" >&2 122 | return 1 123 | fi 124 | # Finally, check that tmux actually works to some degree. 125 | # 126 | # Use a different socket name. On Cygwin, this tmux server is 127 | # slow to exit, and the actual test tmux can attach to it, causing 128 | # problems with missing environment variables. 129 | tmux_check_socket=$(mktemp -d /tmp/mosh-tmux-check.XXXXXXXX) 130 | tmux -f /dev/null -S "${tmux_check_socket}/s" -C new-session true 131 | rv=$? 132 | rm ${tmux_check_socket}/s 133 | rmdir ${tmux_check_socket} 134 | return $rv 135 | } 136 | -------------------------------------------------------------------------------- /src/tests/emulation-80th-column.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test validates the ancient VT100 behavior of positioning the 5 | # cursor at column 80 (and not wrapping) after 80 characters are 6 | # output, and behaving accordingly with subsequent cursor motion 7 | # commands (CR+LF in this state should not result in an extra blank 8 | # line). 9 | # 10 | 11 | # shellcheck source=e2e-test-subrs 12 | . "$(dirname "$0")/e2e-test-subrs" 13 | PATH=$PATH:.:$srcdir 14 | # Top-level wrapper. 15 | if [ $# -eq 0 ]; then 16 | e2e-test "$0" baseline post 17 | exit 18 | fi 19 | 20 | # OK, we have arguments, we're one of the test hooks. 21 | if [ $# -ne 1 ]; then 22 | fail "bad arguments %s\n" "$@" 23 | fi 24 | 25 | baseline() 26 | { 27 | # We need to control CR and LF individually for this test. 28 | TERMIO=$(stty -g) 29 | trap 'stty "$TERMIO"' EXIT 30 | stty raw 31 | printf '\033[H\033[J' 32 | for lines in $(seq 1 25); do 33 | for tencols in $(seq 1 8); do 34 | printf "EEEEEEEEEE" 35 | done 36 | printf "\r\n" 37 | done 38 | } 39 | 40 | post() 41 | { 42 | # If hidden 80th column is working properly, then the lines 43 | # will have no blank lines in between and we should see 23 44 | # of them. 45 | if [ "$(grep -c "EEEEEEEEEE" "$(basename "$0").d/baseline.capture")" -ne 23 ]; then 46 | exit 1 47 | fi 48 | } 49 | 50 | case $1 in 51 | baseline) 52 | baseline;; 53 | post) 54 | post;; 55 | *) 56 | fail "unknown test argument %s\n" "$1";; 57 | esac 58 | -------------------------------------------------------------------------------- /src/tests/emulation-ascii-iso-8859.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This validates display of ASCII and ISO-8859-1 characters. 5 | # 6 | 7 | # shellcheck source=e2e-test-subrs 8 | . "$(dirname "$0")/e2e-test-subrs" 9 | PATH=$PATH:.:$srcdir 10 | # Top-level wrapper. 11 | if [ $# -eq 0 ]; then 12 | e2e-test "$0" baseline direct verify 13 | exit 14 | fi 15 | 16 | # OK, we have arguments, we're one of the test hooks. 17 | if [ $# -ne 1 ]; then 18 | fail "bad arguments %s\n" "$@" 19 | fi 20 | 21 | baseline() 22 | { 23 | printf '\033[H\033[J' 24 | 25 | cat <<'EOF' 26 | 20 21 ! 22 " 23 # 24 $ 25 % 26 & 27 ' 28 ( 29 ) 2a * 2b + 2c , 2d - 2e . 2f / 27 | 30 0 31 1 32 2 33 3 34 4 35 5 36 6 37 7 38 8 39 9 3a : 3b ; 3c < 3d = 3e > 3f ? 28 | 40 @ 41 A 42 B 43 C 44 D 45 E 46 F 47 G 48 H 49 I 4a J 4b K 4c L 4d M 4e N 4f O 29 | 50 P 51 Q 52 R 53 S 54 T 55 U 56 V 57 W 58 X 59 Y 5a Z 5b [ 5c \ 5d ] 5e ^ 5f _ 30 | 60 ` 61 a 62 b 63 c 64 d 65 e 66 f 67 g 68 h 69 i 6a j 6b k 6c l 6d m 6e n 6f o 31 | 70 p 71 q 72 r 73 s 74 t 75 u 76 v 77 w 78 x 79 y 7a z 7b { 7c | 7d } 7e ~ 32 | a0   a1 ¡ a2 ¢ a3 £ a4 ¤ a5 ¥ a6 ¦ a7 § a8 ¨ a9 © aa ª ab « ac ¬ ad ­ ae ® af ¯ 33 | b0 ° b1 ± b2 ² b3 ³ b4 ´ b5 µ b6 ¶ b7 · b8 ¸ b9 ¹ ba º bb » bc ¼ bd ½ be ¾ bf ¿ 34 | c0 À c1 Á c2 Â c3 Ã c4 Ä c5 Å c6 Æ c7 Ç c8 È c9 É ca Ê cb Ë cc Ì cd Í ce Î cf Ï 35 | d0 Ð d1 Ñ d2 Ò d3 Ó d4 Ô d5 Õ d6 Ö d7 × d8 Ø d9 Ù da Ú db Û dc Ü dd Ý de Þ df ß 36 | e0 à e1 á e2 â e3 ã e4 ä e5 å e6 æ e7 ç e8 è e9 é ea ê eb ë ec ì ed í ee î ef ï 37 | f0 ð f1 ñ f2 ò f3 ó f4 ô f5 õ f6 ö f7 ÷ f8 ø f9 ù fa ú fb û fc ü fd ý fe þ ff ÿ 38 | EOF 39 | } 40 | 41 | case $1 in 42 | baseline|direct) 43 | baseline;; 44 | *) 45 | fail "unknown test argument %s\n" "$1";; 46 | esac 47 | -------------------------------------------------------------------------------- /src/tests/emulation-attributes-16color.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-attributes-256color248.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-attributes-256color8.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-attributes-bce.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-attributes-truecolor.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-attributes-vt100.test: -------------------------------------------------------------------------------- 1 | emulation-attributes.test -------------------------------------------------------------------------------- /src/tests/emulation-back-tab.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test is for issue 539 on github. 5 | # 6 | 7 | # shellcheck source=e2e-test-subrs 8 | . "$(dirname "$0")/e2e-test-subrs" 9 | PATH=$PATH:.:$srcdir 10 | # Top-level wrapper. 11 | if [ $# -eq 0 ]; then 12 | e2e-test "$0" baseline post 13 | exit 14 | fi 15 | 16 | # OK, we have arguments, we're one of the test hooks. 17 | if [ $# -ne 1 ]; then 18 | fail "bad arguments %s\n" "$@" 19 | fi 20 | 21 | baseline() 22 | { 23 | printf 'hello, wurld\033[Zo\n' 24 | printf 'hello, wurld\033[2Zo\n' 25 | printf 'hello, wurld\033[99Z9\n' 26 | printf 'hello, wurld\033[It\n' 27 | printf '\033[99I#\n' 28 | } 29 | 30 | post() 31 | { 32 | # Basic previously-failing case. 33 | if grep -q 'hello, wurldo' "$(basename "$0").d/baseline.capture"; then 34 | exit 1 35 | fi 36 | if ! grep -q 'hello, world' "$(basename "$0").d/baseline.capture"; then 37 | exit 99 38 | fi 39 | # New test cases for new code. 40 | if ! grep -q 'oello, wurld' "$(basename "$0").d/baseline.capture" || 41 | ! grep -q '9ello, wurld' "$(basename "$0").d/baseline.capture" || 42 | ! grep -q 'hello, wurld t' "$(basename "$0").d/baseline.capture" || 43 | ! grep -E -q '^ {79}#$' "$(basename "$0").d/baseline.capture"; then 44 | exit 1 45 | fi 46 | exit 0 47 | } 48 | 49 | case $1 in 50 | baseline) 51 | baseline;; 52 | post) 53 | post;; 54 | *) 55 | fail "unknown test argument %s\n" "$1";; 56 | esac 57 | -------------------------------------------------------------------------------- /src/tests/emulation-cursor-motion.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test exercises a particular optimization involving small cursor 5 | # motions in Mosh. 6 | # 7 | 8 | # shellcheck source=e2e-test-subrs 9 | . "$(dirname "$0")/e2e-test-subrs" 10 | PATH=$PATH:.:$srcdir 11 | # Top-level wrapper. 12 | if [ $# -eq 0 ]; then 13 | e2e-test "$0" baseline direct verify 14 | exit 15 | fi 16 | 17 | # OK, we have arguments, we're one of the test hooks. 18 | if [ $# -ne 1 ]; then 19 | fail "bad arguments %s\n" "$@" 20 | fi 21 | 22 | baseline() 23 | { 24 | printf '\033[H\033[J' 25 | 26 | while read -r x y text; do 27 | printf '\033[%d;%dH%s' "$y" "$x" "$text" 28 | sleepf 29 | done <= 256) { 17 | $rc = $? >> 8; 18 | } else { 19 | $rc = ($? & 127) | 128; 20 | } 21 | exit $rc; 22 | -------------------------------------------------------------------------------- /src/tests/inpty.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include "src/include/config.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #if HAVE_PTY_H 47 | #include 48 | #elif HAVE_UTIL_H 49 | #include 50 | #endif 51 | 52 | #if FORKPTY_IN_LIBUTIL 53 | #include 54 | #endif 55 | 56 | #include "src/util/pty_compat.h" 57 | #include "src/util/swrite.h" 58 | 59 | int main( int argc, char* argv[] ) 60 | { 61 | if ( argc < 2 ) { 62 | fprintf( stderr, "usage: inpty COMMAND [ARGS...]\n" ); 63 | return 1; 64 | } 65 | 66 | struct winsize winsize; 67 | memset( &winsize, 0, sizeof( winsize ) ); 68 | winsize.ws_col = 80; 69 | winsize.ws_row = 24; 70 | 71 | int saved_stderr = dup( STDERR_FILENO ); 72 | if ( saved_stderr < 0 ) { 73 | perror( "dup" ); 74 | return 1; 75 | } 76 | 77 | int master; 78 | pid_t child = forkpty( &master, NULL, NULL, &winsize ); 79 | if ( child == -1 ) { 80 | perror( "forkpty" ); 81 | /* The Debian and Ubuntu build systems fail to set up a working 82 | * /dev/ptmx (https://bugs.debian.org/817236). There is not much 83 | * we can do about that except skip the test. In the future when 84 | * this is fixed, we should turn this into an failure. 85 | */ 86 | return 77; 87 | } else if ( child == 0 ) { 88 | if ( dup2( saved_stderr, STDERR_FILENO ) < 0 ) { 89 | perror( "dup2" ); 90 | exit( 1 ); 91 | } 92 | if ( close( saved_stderr ) < 0 ) { 93 | perror( "close" ); 94 | exit( 1 ); 95 | } 96 | if ( execvp( argv[1], argv + 1 ) < 0 ) { 97 | perror( "execve" ); 98 | exit( 1 ); 99 | } 100 | exit( 0 ); 101 | } 102 | 103 | while ( 1 ) { 104 | char buf[1024]; 105 | ssize_t bytes_read = read( master, buf, sizeof( buf ) ); 106 | if ( bytes_read == 0 || ( bytes_read < 0 && errno == EIO ) ) { /* EOF */ 107 | break; 108 | } else if ( bytes_read < 0 ) { 109 | perror( "read" ); 110 | return 1; 111 | } 112 | swrite( STDOUT_FILENO, buf, bytes_read ); 113 | } 114 | 115 | int wstatus; 116 | if ( waitpid( child, &wstatus, 0 ) < 0 ) { 117 | perror( "waitpid" ); 118 | return 1; 119 | } 120 | 121 | if ( WIFSIGNALED( wstatus ) ) { 122 | fprintf( stderr, "inpty: child exited with signal %d\n", WTERMSIG( wstatus ) ); 123 | raise( WTERMSIG( wstatus ) ); 124 | return -1; 125 | } else { 126 | return WIFEXITED( wstatus ) ? WEXITSTATUS( wstatus ) : -1; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/tests/is-utf8-locale.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | 35 | #include "src/util/locale_utils.h" 36 | 37 | int main( int argc __attribute__( ( unused ) ), char** argv __attribute__( ( unused ) ) ) 38 | { 39 | set_native_locale(); 40 | if ( !is_utf8_locale() ) { 41 | fprintf( stderr, "not a UTF-8 locale\n" ); 42 | return 1; 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/tests/local.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . "$(dirname "$0")/e2e-test-subrs" 4 | if ! set_locale; then 5 | echo "$0: no usable locale" >&2 6 | exit 99 7 | fi 8 | 9 | set -eu 10 | out=$( 11 | TERM=xterm \ 12 | ./inpty \ 13 | ../../scripts/mosh \ 14 | --client="../frontend/mosh-client" \ 15 | --server="$PWD/../frontend/mosh-server" \ 16 | --local --bind-server=127.0.0.1 127.0.0.1 \ 17 | -- printf 'he%s\n' llo) 18 | case "$out" in 19 | *hello*) exit 0;; 20 | *) exit 1;; 21 | esac 22 | -------------------------------------------------------------------------------- /src/tests/mosh-client: -------------------------------------------------------------------------------- 1 | e2e-test -------------------------------------------------------------------------------- /src/tests/mosh-server: -------------------------------------------------------------------------------- 1 | e2e-test -------------------------------------------------------------------------------- /src/tests/network-no-diff.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This is a regression test to ensure that Mosh does not spin 5 | # on updates that do not actually change the framebuffer. 6 | # 7 | 8 | # shellcheck source=e2e-test-subrs 9 | . "$(dirname "$0")/e2e-test-subrs" 10 | PATH=$PATH:.:$srcdir 11 | # Top-level wrapper. 12 | if [ $# -eq 0 ]; then 13 | e2e-test "$0" baseline post 14 | exit 15 | fi 16 | 17 | # OK, we have arguments, we're one of the test hooks. 18 | if [ $# -ne 1 ]; then 19 | fail "bad arguments %s\n" "$@" 20 | fi 21 | 22 | baseline() 23 | { 24 | # Generate updates that don't change the screen 25 | i=0 26 | while [ $i -lt 10 ] && printf 'x\b' && sleep 1; do 27 | i=$((i + 1)) 28 | done 29 | } 30 | 31 | post() 32 | { 33 | # Extract server run time. 34 | runtime=$(sed -E -n 's/.*@@@ runtime: (.*) @@@.*/\1/p' "$(basename "$0").d/baseline.tmux.log") 35 | 36 | # If this system can't actually report runtime, bail. 37 | if [ -z "$runtime" ] || [ "$runtime" -eq "-" ]; then 38 | exit 0 39 | fi 40 | 41 | # If we ran for more than one second, fail. 42 | seconds=${runtime##*:} 43 | bigger=${runtime%:*} 44 | onesec=$(echo "$seconds >= 1" | bc) 45 | if [ "$onesec" -eq 1 ] || [ "$bigger" -ne 0 ]; then 46 | exit 1 47 | fi 48 | exit 0 49 | } 50 | 51 | case $1 in 52 | baseline) 53 | baseline;; 54 | post) 55 | post;; 56 | *) 57 | fail "unknown test argument %s\n" "$1";; 58 | esac 59 | -------------------------------------------------------------------------------- /src/tests/nonce-incr.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | /* Tests that the Mosh network layer seems to be using unique nonces */ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #include "src/network/network.h" 40 | 41 | int main() 42 | { 43 | std::set nonces; 44 | const unsigned int NUM_EXAMPLES = 1000000; 45 | 46 | for ( unsigned int i = 0; i < NUM_EXAMPLES; i++ ) { 47 | Network::Packet packet( Network::TO_CLIENT, 0, 0, "test" ); 48 | nonces.insert( packet.toMessage().nonce.val() ); 49 | } 50 | 51 | for ( unsigned int i = 0; i < NUM_EXAMPLES; i++ ) { 52 | Network::Packet packet( Network::TO_SERVER, 0, 0, "test" ); 53 | nonces.insert( packet.toMessage().nonce.val() ); 54 | } 55 | 56 | for ( unsigned int i = 0; i < NUM_EXAMPLES; i++ ) { 57 | { 58 | Network::Packet packet( Network::TO_SERVER, 0, 0, "test" ); 59 | nonces.insert( packet.toMessage().nonce.val() ); 60 | } 61 | 62 | { 63 | Network::Packet packet( Network::TO_CLIENT, 0, 0, "test" ); 64 | nonces.insert( packet.toMessage().nonce.val() ); 65 | } 66 | } 67 | 68 | if ( nonces.size() == 4 * NUM_EXAMPLES ) { 69 | return EXIT_SUCCESS; 70 | } 71 | 72 | return EXIT_FAILURE; 73 | } 74 | -------------------------------------------------------------------------------- /src/tests/prediction-unicode.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This is a regression test for a bug seen where mosh-client's 5 | # prediction code would sometimes show "gück" when "glück" was typed. 6 | # mosh-client would output a predicted Unicode input character 7 | # first as an 8-bit character containing the lowest 8 bits of the 8 | # Unicode code point, then redraw it correctly with its UTF-8 sequence 9 | # when the prediction is validated. For many accented Latin 10 | # characters, the 8-bit character is an illegal UTF-8 code sequence. 11 | # Most terminal emulators will output the Unicode replacement 12 | # character, which is only visible until validation. urxvt, however, 13 | # draws no character and does not change the cursor location on an 14 | # illegal UTF-8 sequence, causing this bug to be visible as ongoing 15 | # display corruption. A subset of wide characters (including CJK) 16 | # will show display corruption with all terminal emulators, because a 17 | # narrow replacement character will be drawn when a wide character 18 | # should have been. 19 | # 20 | # tmux draws a replacement character for invalid UTF-8, and we 21 | # depend on that in this test. 22 | # 23 | # Another similar failing case is typing "faĩl". In this case the "ĩ" 24 | # would be predicted as ")" before being replaced by the 25 | # correct character. 26 | # 27 | 28 | # shellcheck source=e2e-test-subrs 29 | . "$(dirname "$0")/e2e-test-subrs" 30 | PATH=$PATH:.:$srcdir 31 | # Top-level wrapper. 32 | if [ $# -eq 0 ]; then 33 | e2e-test "$0" tmux baseline mosh-args post 34 | exit 35 | fi 36 | 37 | tmux_commands() 38 | { 39 | for x in $(seq 1 5); do 40 | for y in $(seq 1 5); do 41 | for i in "gl" ü "ck fa" ĩ "l "; do 42 | printf "send-keys '%s'\n" "$i" 43 | sleepf 44 | done 45 | done 46 | printf "send-keys 0x0d\n" 47 | done 48 | printf "send-keys 0x0d\n" 49 | sleep 1 50 | printf "send-keys 0x04\n" 51 | # Unreliable on Cygwin under load, it seems. 52 | sleep 1 53 | printf "send-keys 0x04\n" 54 | # This will get killed by SIGPIPE. 55 | while printf "show-options\n" && sleep 1; do 56 | : 57 | done 58 | } 59 | 60 | tmux_stdin() 61 | { 62 | tmux_commands | "$@" 63 | exit 64 | } 65 | 66 | baseline() 67 | { 68 | # Just receive and toss input in canonical mode. 69 | cat > /dev/null 70 | } 71 | 72 | post() 73 | { 74 | # Look for bad output: ')' or \374 75 | ( 76 | unset LC_ALL 77 | unset LC_CTYPE 78 | unset LANGUAGE 79 | ! env LANG=C egrep -q "%output %0 (\)|$(printf \\374))" "$(basename "$0").d/baseline.tmux.log" 80 | # Implicit exitcode return. 81 | ) 82 | return $? 83 | } 84 | 85 | case $1 in 86 | tmux) 87 | shift; 88 | tmux_stdin "$@";; 89 | baseline) 90 | baseline;; 91 | mosh-args) 92 | printf "%s\n" "--predict=always";; 93 | post) 94 | post;; 95 | *) 96 | fail "unknown test argument %s\n" "$1";; 97 | esac 98 | -------------------------------------------------------------------------------- /src/tests/print-exitstatus: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | # 4 | # Print exitstatus on stderr. 5 | # 6 | use warnings; 7 | use strict; 8 | 9 | my $rc = system(@ARGV); 10 | if ($? == -1) { 11 | die "system failed: %!\n"; 12 | } 13 | if ($? == 0) { 14 | $rc = 0; 15 | } elsif ($? >= 256) { 16 | $rc = $? >> 8; 17 | } else { 18 | $rc = ($? & 127) | 128; 19 | } 20 | print STDERR "@@@ exitstatus: ${rc} @@@\n"; 21 | # Now look for it in log file. 22 | my $grepfilename = $ENV{'MOSH_E2E_TEST'} . ".tmux.log"; 23 | for my $i (1..600) { 24 | open(my $grepfile, "<", $grepfilename) or die; 25 | while (<$grepfile>) { 26 | chomp; 27 | /@@@ exitstatus: .* @@@/ && goto gotit; 28 | } 29 | close($grepfile); 30 | sleep .1; 31 | } 32 | gotit: 33 | exit $rc; 34 | -------------------------------------------------------------------------------- /src/tests/pty-deadlock.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This is a regression test for a BSD pty bug in Mosh. On 5 | # FreeBSD/OpenBSD/OS X, a pty master can block on read() after 6 | # select() has informed us that there is data available, if a ^S is 7 | # written to the pty master between the select() and the read(). 8 | # 9 | # Unfortunately, everything attached to the pty gets stuck when this 10 | # happens. If this tests fails, you will need to do some manual 11 | # cleanup with kill -9. 12 | # 13 | 14 | # shellcheck source=e2e-test-subrs 15 | . "$(dirname "$0")/e2e-test-subrs" 16 | PATH=$PATH:.:$srcdir 17 | # Top-level wrapper. 18 | if [ $# -eq 0 ]; then 19 | e2e-test "$0" tmux baseline post 20 | exit 21 | fi 22 | 23 | tmux_commands() 24 | { 25 | # An interactive shell is waiting for us in the mosh session. 26 | # Start test... 27 | sleep 2 28 | printf "send-keys 0x0d\n" 29 | sleep 5 30 | # Stop output... 31 | printf "send-keys 0x13\n" 32 | sleep 10 33 | # Restart output... 34 | printf "send-keys 0x11\n" 35 | sleep 10 36 | # And stop the test script, so it produces its exit messge. 37 | printf "send-keys 0x0d\n" 38 | # This will get killed by SIGPIPE. 39 | while printf "show-options\n" && sleep 1; do 40 | : 41 | done 42 | } 43 | 44 | tmux_stdin() 45 | { 46 | tmux_commands | "$@" 47 | exit 48 | } 49 | 50 | baseline() 51 | { 52 | # Make a lot of noise on stdout to keep mosh busy, and exit 53 | # with a distinctive message when we get a CR. Exit after 10s in any case. 54 | blat=$(for i in $(seq 1 100); do 55 | printf 'a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n' 56 | done) 57 | read -r x 58 | while printf '%s' "$blat"; do 59 | : 60 | done & 61 | printpid=$! 62 | (sleep 120; kill $$ $printpid) & 63 | killpid=$! 64 | read -r x 65 | kill $printpid 66 | # Try and make sure the printer stops writing before the following printf 67 | sleep 1 68 | printf "\n=== normal exit ===\n" 69 | # Let tty queues drain, so the exit message gets to mosh-client 70 | # before we exit 71 | sleep 4 72 | # Kill the killer and exit normally. 73 | kill $killpid 74 | } 75 | 76 | post() 77 | { 78 | if grep -q '=== normal exit ===' "$(basename "$0").d/baseline.capture"; then 79 | exit 0 80 | fi 81 | exit 1 82 | } 83 | 84 | case $1 in 85 | tmux) 86 | shift; 87 | tmux_stdin "$@";; 88 | baseline) 89 | baseline;; 90 | post) 91 | post;; 92 | *) 93 | fail "unknown test argument %s\n" "$1";; 94 | esac 95 | -------------------------------------------------------------------------------- /src/tests/repeat-with-input.test: -------------------------------------------------------------------------------- 1 | repeat.test -------------------------------------------------------------------------------- /src/tests/repeat.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Run mosh many times. If run as repeat-with-stdin.test, also send 5 | # input constantly, to try and trigger a bug where mosh-server would 6 | # exit on OS X if input was received after the client session had 7 | # exited. 8 | # 9 | 10 | # 100 iterations runs in comparable time to other tests. 11 | : ${REPEAT_TEST_LOOPCOUNT:=100} 12 | 13 | # shellcheck source=e2e-test-subrs 14 | . "$(dirname "$0")/e2e-test-subrs" 15 | PATH=$PATH:.:$srcdir 16 | 17 | # Top-level wrapper. 18 | if [ $# -eq 0 ]; then 19 | do_tmux= 20 | case $(basename "$0" .test) in 21 | repeat-with-input) 22 | do_tmux=tmux;; 23 | esac 24 | e2e-test "$0" baseline client server ${do_tmux} 25 | exit 26 | fi 27 | 28 | # Run mosh repeatedly 29 | client() 30 | { 31 | for i in $(seq 1 $REPEAT_TEST_LOOPCOUNT); do 32 | (sleep 15; kill $$) & 33 | killpid=$! 34 | if ! "$@"; then 35 | printf "### iteration %d failed\n" "$i" 36 | kill $killpid 37 | exit 1 38 | fi 39 | kill $killpid 40 | done 41 | } 42 | 43 | # e2e-test-server is slow because of its screen capture; this simple 44 | # wrapper is faster. 45 | server() 46 | { 47 | shift 48 | eval "$@" 49 | } 50 | 51 | # Constantly send keyboard input. 52 | tmux_commands() 53 | { 54 | while printf "send-keys 0x0d\n" && sleepf; do 55 | : 56 | done 57 | } 58 | 59 | tmux_stdin() 60 | { 61 | tmux_commands | "$@" 62 | exit 63 | } 64 | 65 | baseline() 66 | { 67 | printf "@@@ done\n" 68 | } 69 | 70 | post() 71 | { 72 | if [ "$(grep -c "@@@ done" "$(basename "$0").d/baseline.tmux.log")" -lt $REPEAT_TEST_LOOPCOUNT ]; then 73 | exit 1 74 | fi 75 | } 76 | 77 | case $1 in 78 | tmux) 79 | shift; 80 | tmux_stdin "$@";; 81 | baseline) 82 | baseline;; 83 | client) 84 | shift 85 | client "$@";; 86 | server) 87 | shift 88 | server "$@";; 89 | *) 90 | fail "unknown test argument %s\n" "$1";; 91 | esac 92 | -------------------------------------------------------------------------------- /src/tests/server-network-timeout.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test checks for operation of the MOSH_SERVER_NETWORK_TMOUT variable. 5 | # It does this by 6 | # * setting the variable 7 | # * killing the client (and its network traffic) 8 | # * waiting server-side, for the server to die 9 | # If it is killed, the test is successful. 10 | # If it survives that long and the server is still around, the test fails. 11 | # The client waits a bit longer than the server so that status can be collected 12 | # properly. 13 | # 14 | 15 | TIMEOUT=10 16 | 17 | # shellcheck source=e2e-test-subrs 18 | . "$(dirname "$0")/e2e-test-subrs" 19 | PATH=$PATH:.:$srcdir 20 | # Top-level wrapper. 21 | if [ $# -eq 0 ]; then 22 | e2e-test "$0" client baseline 23 | exit 24 | fi 25 | 26 | # OK, we have arguments, we're one of the test hooks. 27 | 28 | client() 29 | { 30 | case "$myname" in 31 | server-network-timeout) 32 | export MOSH_SERVER_NETWORK_TMOUT=$TIMEOUT;; 33 | server-signal-timeout) 34 | export MOSH_SERVER_SIGNAL_TMOUT=$TIMEOUT;; 35 | *) 36 | fail "unexpected test name %s\n" "$myname" 37 | esac 38 | shift 39 | # Print this early, because the server is expected to die before 40 | # the normal time this is sent by e2e-test-server. 41 | printf "@@@ server complete @@@\n" >&2 42 | # Run mosh SUT. 43 | eval "$@" 44 | # The client may be murdered. We need to expect that... 45 | retval=$? 46 | case $retval in 47 | 0|1) 48 | fail "mosh-client had a normal exit\n";; # test condition failed 49 | 9|137|265) 50 | # Aha, signal 9. Wait. 51 | sleep $(( TIMEOUT + 12 )) 52 | exit 0 53 | ;; 54 | *) 55 | fail "unknown client wrapper failure, retval=%d\n" $retval 56 | ;; 57 | esac 58 | fail "client wrapper shouldnt get here\n" 59 | } 60 | baseline() 61 | { 62 | # check for our wonderful variable 63 | if [ -z "$MOSH_SERVER_NETWORK_TMOUT" ] && [ -z "$MOSH_SERVER_SIGNAL_TMOUT" ]; then 64 | env 65 | fail "Variable unset\n" 66 | fi 67 | # check for our client 68 | if [ -z "$MOSH_CLIENT_PID" ]; then 69 | env 70 | fail "Client pid unavailable\n" 71 | fi 72 | if ! kill -0 "$MOSH_CLIENT_PID"; then 73 | fail "mosh client is unexpectedly missing\n" 74 | fi 75 | 76 | # Set up for good return and cleanup on being killed 77 | trap "echo got killed >&2; sleep 1; exit 0" HUP TERM 78 | sleep 1 79 | 80 | # Kill the client, to stop network traffic. 81 | kill -KILL "$MOSH_CLIENT_PID" 82 | case "$myname" in 83 | server-network-timeout) 84 | # Just wait. This is the hardest part. 85 | sleep $(( TIMEOUT + 7 )) 86 | ;; 87 | server-signal-timeout) 88 | # Wait for the timeout to expire. 89 | sleep $(( TIMEOUT + 2 )) 90 | # Tell the server to go away. 91 | kill -USR1 "$MOSH_SERVER_PID" 92 | sleep 5 93 | ;; 94 | *) 95 | fail "unexpected test name %s\n" "$myname" 96 | esac 97 | # If we're still alive and the server is too, the test failed. 98 | # XXX the server is getting killed and we're getting here anyway. 99 | # Exit with error only if server is still around. 100 | sleep 1 101 | ! kill -0 "$MOSH_SERVER_PID" 102 | exit 103 | } 104 | 105 | myname="$(basename "$0" .test)" 106 | 107 | case $1 in 108 | baseline|variant) 109 | baseline;; 110 | client) 111 | client "$@";; 112 | *) 113 | fail "unknown test argument %s\n" "$1";; 114 | esac 115 | -------------------------------------------------------------------------------- /src/tests/server-signal-timeout.test: -------------------------------------------------------------------------------- 1 | server-network-timeout.test -------------------------------------------------------------------------------- /src/tests/test_utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | 35 | #include "test_utils.h" 36 | 37 | void hexdump( const void* buf, size_t len, const char* name ) 38 | { 39 | const unsigned char* data = (const unsigned char*)buf; 40 | printf( DUMP_NAME_FMT, name ); 41 | for ( size_t i = 0; i < len; i++ ) { 42 | // Although data[i] is an unsigned char, it will be promoted to a signed int 43 | // when passed as an argument. Explicitly cast it back to an unsigned type 44 | // so it can be printed in hex. 45 | printf( "%02x", static_cast( data[i] ) ); 46 | } 47 | printf( "\n" ); 48 | } 49 | 50 | void hexdump( const Crypto::AlignedBuffer& buf, const char* name ) 51 | { 52 | hexdump( buf.data(), buf.len(), name ); 53 | } 54 | 55 | void hexdump( const std::string& buf, const char* name ) 56 | { 57 | hexdump( buf.data(), buf.size(), name ); 58 | } 59 | -------------------------------------------------------------------------------- /src/tests/test_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TEST_UTILS_HPP 34 | #define TEST_UTILS_HPP 35 | 36 | #include 37 | 38 | #include "src/crypto/crypto.h" 39 | 40 | #define DUMP_NAME_FMT "%-10s " 41 | 42 | void hexdump( const void* buf, size_t len, const char* name ); 43 | void hexdump( const Crypto::AlignedBuffer& buf, const char* name ); 44 | void hexdump( const std::string& buf, const char* name ); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/tests/unicode-combine-fallback-assert.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test is for Github issue 667 5 | # https://github.com/mobile-shell/mosh/issues/667 6 | # where mosh will assert when a combining character is printed on a 7 | # just-cleared cell. 8 | # 9 | # It just sends the offending output to mosh and expects it to not die. 10 | 11 | # shellcheck source=e2e-test-subrs 12 | . "$(dirname "$0")/e2e-test-subrs" 13 | PATH=$PATH:.:$srcdir 14 | # Top-level wrapper. 15 | if [ $# -eq 0 ]; then 16 | e2e-test "$0" baseline 17 | exit 18 | fi 19 | 20 | # OK, we have arguments, we're one of the test hooks. 21 | if [ $# -ne 1 ]; then 22 | fail "bad arguments %s\n" "$@" 23 | fi 24 | 25 | baseline() 26 | { 27 | printf '0\033[1J\xcc\xb4' 28 | } 29 | 30 | case $1 in 31 | baseline) 32 | baseline;; 33 | *) 34 | fail "unknown test argument %s\n" "$1";; 35 | esac 36 | -------------------------------------------------------------------------------- /src/tests/unicode-later-combining.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This test is for the first Unicode issue described on the Mosh web 5 | # page, a combining character drawn on a cell after returning the 6 | # cursor to that cell. 7 | # 8 | # We print 'COMBINING CIRCUMFLEX ACCENT' (U+0302) onto an unused cell. 9 | # We expect Mosh to output U+0020, U+0302 for that character cell (or 10 | # possibly U+00A0, U+0302). 11 | # 12 | # XXX This test is fragile because it depends on tmux's unicode rendering. 13 | # The baseline and variant tests produce different (but valid) outputs 14 | # that are visually identical. The variant test is not run or validated. 15 | # 16 | 17 | # shellcheck source=e2e-test-subrs 18 | . "$(dirname "$0")/e2e-test-subrs" 19 | PATH=$PATH:.:$srcdir 20 | # Top-level wrapper. 21 | if [ $# -eq 0 ]; then 22 | e2e-test "$0" baseline post 23 | exit 24 | fi 25 | 26 | # OK, we have arguments, we're one of the test hooks. 27 | if [ $# -ne 1 ]; then 28 | fail "bad arguments %s\n" "$@" 29 | fi 30 | 31 | baseline() 32 | { 33 | printf 'abc\n\314\202\ndef\n' 34 | } 35 | 36 | variant() 37 | { 38 | printf 'abc\n \314\202\ndef\n' 39 | } 40 | 41 | post() 42 | { 43 | export LANG=C 44 | if [ "$(tmux -V)" = "tmux 2.4" ]; then 45 | skip "tmux 2.4 unicode combining bug breaks this test\n" 46 | fi 47 | if grep -q "$(printf '^\302\240\314\202$')" "$(basename "$0").d/baseline.capture"; then 48 | exit 0 49 | fi 50 | exit 1 51 | } 52 | 53 | case $1 in 54 | baseline) 55 | baseline;; 56 | variant) 57 | variant;; 58 | post) 59 | post;; 60 | *) 61 | fail "unknown test argument %s\n" "$1";; 62 | esac 63 | -------------------------------------------------------------------------------- /src/tests/window-resize.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This is a regression test for window resizing in Mosh. Making it 5 | # happen is a little kludgy: we have to create other panes in tmux and 6 | # resize them. But it works! 7 | # 8 | 9 | # shellcheck source=e2e-test-subrs 10 | . "$(dirname "$0")/e2e-test-subrs" 11 | PATH=$PATH:.:$srcdir 12 | # Top-level wrapper. 13 | if [ $# -eq 0 ]; then 14 | e2e-test "$0" tmux baseline 15 | exit 16 | fi 17 | 18 | tmux_resize_commands() 19 | { 20 | hv=$1 21 | shrink=$2 22 | grow=$3 23 | # Split the window into two panes. 24 | printf "split-window -%s\n" "${hv}" 25 | # Shrink the pane we created 26 | for i in $(seq 1 10); do 27 | sleepf 28 | printf "resize-pane -%s\n" "${shrink}" 29 | done 30 | # And grow it 31 | for i in $(seq 1 10); do 32 | sleepf 33 | printf "resize-pane -%s\n" "${grow}" 34 | done 35 | sleep 1 36 | # Remove the pane we created. 37 | printf "kill-pane\n" 38 | } 39 | 40 | tmux_commands() 41 | { 42 | # An interactive shell is waiting for us in the mosh session. 43 | # Start a full screen application that will redraw on window 44 | # resize. 45 | printf "send-keys 'less \"%s\"' 0x0d\n" "${srcdir}/e2e-test" 46 | sleep 1 47 | # we control the horizontal... 48 | tmux_resize_commands v D U 49 | sleep 1 50 | # and the vertical. 51 | tmux_resize_commands h L R 52 | sleep 1 53 | # Exit less. 54 | printf "send-keys 'q'\n" 55 | sleep 1 56 | # Exit mosh session shell. 57 | printf "send-keys 'exit 0' 0x0d\n" 58 | # need to sleep extra long here, to let child commands complete, 59 | # and not have tmux exit prematurely 60 | sleep 5 61 | } 62 | 63 | tmux_stdin() 64 | { 65 | tmux_commands | "$@" 66 | exit 67 | } 68 | 69 | baseline() 70 | { 71 | # Just start an interactive shell and wait. The tmux action drives. 72 | sh 73 | } 74 | 75 | case $1 in 76 | tmux) 77 | shift; 78 | tmux_stdin "$@";; 79 | baseline) 80 | baseline;; 81 | *) 82 | fail "unknown test argument %s\n" "$1";; 83 | esac 84 | -------------------------------------------------------------------------------- /src/util/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = -I$(top_srcdir)/ $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) 2 | 3 | noinst_LIBRARIES = libmoshutil.a 4 | 5 | libmoshutil_a_SOURCES = locale_utils.cc locale_utils.h swrite.cc swrite.h dos_assert.h fatal_assert.h select.h select.cc timestamp.h timestamp.cc pty_compat.cc pty_compat.h 6 | -------------------------------------------------------------------------------- /src/util/dos_assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef DOS_ASSERT_HPP 34 | #define DOS_ASSERT_HPP 35 | 36 | #include 37 | #include 38 | 39 | #include "src/crypto/crypto.h" 40 | 41 | static void dos_detected( const char* expression, const char* file, int line, const char* function ) 42 | { 43 | char buffer[2048]; 44 | snprintf( buffer, 45 | 2048, 46 | "Illegal counterparty input (possible denial of service) in function %s at %s:%d, failed test: %s\n", 47 | function, 48 | file, 49 | line, 50 | expression ); 51 | throw Crypto::CryptoException( buffer ); 52 | } 53 | 54 | #define dos_assert( expr ) ( ( expr ) ? (void)0 : dos_detected( #expr, __FILE__, __LINE__, __func__ ) ) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/util/fatal_assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef FATAL_ASSERT_HPP 34 | #define FATAL_ASSERT_HPP 35 | 36 | #include 37 | #include 38 | 39 | static void fatal_error( const char* expression, const char* file, int line, const char* function ) 40 | { 41 | fprintf( stderr, 42 | "Fatal assertion failure in function %s at %s:%d\nFailed test: %s\n", 43 | function, 44 | file, 45 | line, 46 | expression ); 47 | abort(); 48 | } 49 | 50 | #define fatal_assert( expr ) ( ( expr ) ? (void)0 : fatal_error( #expr, __FILE__, __LINE__, __func__ ) ) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/util/locale_utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include "src/include/config.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #if HAVE_LANGINFO_H 43 | #include 44 | #endif 45 | 46 | #include "src/util/locale_utils.h" 47 | 48 | const std::string LocaleVar::str( void ) const 49 | { 50 | if ( name.empty() ) { 51 | return std::string( "[no charset variables]" ); 52 | } 53 | return name + "=" + value; 54 | } 55 | 56 | const LocaleVar get_ctype( void ) 57 | { 58 | /* Reimplement the search logic, just for diagnostics */ 59 | if ( const char* all = getenv( "LC_ALL" ) ) { 60 | return LocaleVar( "LC_ALL", all ); 61 | } else if ( const char* ctype = getenv( "LC_CTYPE" ) ) { 62 | return LocaleVar( "LC_CTYPE", ctype ); 63 | } else if ( const char* lang = getenv( "LANG" ) ) { 64 | return LocaleVar( "LANG", lang ); 65 | } 66 | return LocaleVar( "", "" ); 67 | } 68 | 69 | const char* locale_charset( void ) 70 | { 71 | static const char ASCII_name[] = "US-ASCII"; 72 | 73 | /* Produce more pleasant name of US-ASCII */ 74 | const char* ret = nl_langinfo( CODESET ); 75 | 76 | if ( strcmp( ret, "ANSI_X3.4-1968" ) == 0 ) { 77 | ret = ASCII_name; 78 | } 79 | 80 | return ret; 81 | } 82 | 83 | bool is_utf8_locale( void ) 84 | { 85 | /* Verify locale calls for UTF-8 */ 86 | if ( strcmp( locale_charset(), "UTF-8" ) != 0 && strcmp( locale_charset(), "utf-8" ) != 0 ) { 87 | return false; 88 | } 89 | return true; 90 | } 91 | 92 | void set_native_locale( void ) 93 | { 94 | /* Adopt native locale */ 95 | if ( NULL == setlocale( LC_ALL, "" ) ) { 96 | int saved_errno = errno; 97 | if ( saved_errno == ENOENT ) { 98 | LocaleVar ctype( get_ctype() ); 99 | fprintf( stderr, "The locale requested by %s isn't available here.\n", ctype.str().c_str() ); 100 | if ( !ctype.name.empty() ) { 101 | fprintf( stderr, "Running `locale-gen %s' may be necessary.\n\n", ctype.value.c_str() ); 102 | } 103 | } else { 104 | errno = saved_errno; 105 | perror( "setlocale" ); 106 | } 107 | } 108 | } 109 | 110 | void clear_locale_variables( void ) 111 | { 112 | unsetenv( "LANG" ); 113 | unsetenv( "LANGUAGE" ); 114 | unsetenv( "LC_CTYPE" ); 115 | unsetenv( "LC_NUMERIC" ); 116 | unsetenv( "LC_TIME" ); 117 | unsetenv( "LC_COLLATE" ); 118 | unsetenv( "LC_MONETARY" ); 119 | unsetenv( "LC_MESSAGES" ); 120 | unsetenv( "LC_PAPER" ); 121 | unsetenv( "LC_NAME" ); 122 | unsetenv( "LC_ADDRESS" ); 123 | unsetenv( "LC_TELEPHONE" ); 124 | unsetenv( "LC_MEASUREMENT" ); 125 | unsetenv( "LC_IDENTIFICATION" ); 126 | unsetenv( "LC_ALL" ); 127 | } 128 | -------------------------------------------------------------------------------- /src/util/locale_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef LOCALE_UTILS_HPP 34 | #define LOCALE_UTILS_HPP 35 | 36 | #include 37 | 38 | class LocaleVar 39 | { 40 | public: 41 | const std::string name, value; 42 | LocaleVar( const char* s_name, const char* s_value ) : name( s_name ), value( s_value ) {} 43 | const std::string str( void ) const; 44 | }; 45 | 46 | const LocaleVar get_ctype( void ); 47 | const char* locale_charset( void ); 48 | bool is_utf8_locale( void ); 49 | void set_native_locale( void ); 50 | void clear_locale_variables( void ); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/util/pty_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef PTY_COMPAT_HPP 34 | #define PTY_COMPAT_HPP 35 | 36 | #include "src/include/config.h" 37 | 38 | #ifndef HAVE_FORKPTY 39 | #define forkpty my_forkpty 40 | #endif 41 | #ifndef HAVE_CFMAKERAW 42 | #define cfmakeraw my_cfmakeraw 43 | #endif 44 | 45 | pid_t my_forkpty( int* amaster, char* name, const struct termios* termp, const struct winsize* winp ); 46 | 47 | void my_cfmakeraw( struct termios* termios_p ); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/util/select.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include "src/util/select.h" 34 | 35 | fd_set Select::dummy_fd_set; 36 | 37 | sigset_t Select::dummy_sigset; 38 | 39 | unsigned int Select::verbose = 0; 40 | 41 | void Select::handle_signal( int signum ) 42 | { 43 | fatal_assert( signum >= 0 ); 44 | fatal_assert( signum <= MAX_SIGNAL_NUMBER ); 45 | 46 | Select& sel = get_instance(); 47 | sel.got_signal[signum] = 1; 48 | } 49 | -------------------------------------------------------------------------------- /src/util/swrite.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include "src/util/swrite.h" 39 | 40 | int swrite( int fd, const char* str, ssize_t len ) 41 | { 42 | ssize_t total_bytes_written = 0; 43 | ssize_t bytes_to_write = ( len >= 0 ) ? len : (ssize_t)strlen( str ); 44 | while ( total_bytes_written < bytes_to_write ) { 45 | ssize_t bytes_written = write( fd, str + total_bytes_written, bytes_to_write - total_bytes_written ); 46 | if ( bytes_written <= 0 ) { 47 | perror( "write" ); 48 | return -1; 49 | } 50 | total_bytes_written += bytes_written; 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/util/swrite.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef SWRITE_HPP 34 | #define SWRITE_HPP 35 | 36 | int swrite( int fd, const char* str, ssize_t len = -1 ); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/util/timestamp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mosh: the mobile shell 3 | Copyright 2012 Keith Winstein 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | In addition, as a special exception, the copyright holders give 19 | permission to link the code of portions of this program with the 20 | OpenSSL library under certain conditions as described in each 21 | individual source file, and distribute linked combinations including 22 | the two. 23 | 24 | You must obey the GNU General Public License in all respects for all 25 | of the code used other than OpenSSL. If you modify file(s) with this 26 | exception, you may extend this exception to your version of the 27 | file(s), but you are not obligated to do so. If you do not wish to do 28 | so, delete this exception statement from your version. If you delete 29 | this exception statement from all source files in the program, then 30 | also delete it here. 31 | */ 32 | 33 | #ifndef TIMESTAMP_HPP 34 | #define TIMESTAMP_HPP 35 | 36 | #include 37 | 38 | void freeze_timestamp( void ); 39 | uint64_t frozen_timestamp( void ); 40 | 41 | #endif 42 | --------------------------------------------------------------------------------