├── .gitignore ├── .travis.yml ├── AUTHORS ├── COPYING ├── COPYING.iOS ├── ChangeLog ├── Makefile.am ├── NEWS ├── README.md ├── THANKS ├── autogen.sh ├── build-package.sh ├── conf ├── Makefile.am ├── bash-completion │ └── completions │ │ └── mosh └── ufw │ └── applications.d │ └── mosh ├── configure.ac ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── mosh.maintscript ├── rules ├── source │ └── format └── watch ├── fedora └── mosh.spec ├── m4 ├── ax_check_compile_flag.m4 ├── ax_check_library.m4 ├── ax_check_link_flag.m4 ├── ax_with_curses.m4 └── pkg.m4 ├── macosx ├── .gitignore ├── Distribution.in ├── build.sh ├── copying.rtf ├── mosh-package.pmdoc.in │ ├── 01prefix-contents.xml │ ├── 01prefix.xml │ └── index.xml └── readme.rtf ├── man ├── Makefile.am ├── mosh-client.1 ├── mosh-server.1 └── mosh.1 ├── my_configure.sh ├── 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.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 ├── network ├── Makefile.am ├── addresses.cc ├── addresses.h ├── compressor.cc ├── compressor.h ├── network.cc ├── network.h ├── networktransport.cc ├── networktransport.h ├── transportfragment.cc ├── transportfragment.h ├── transportsender.cc ├── 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 ├── encrypt-decrypt.cc ├── ocb-aes.cc ├── test_utils.cc └── test_utils.h └── util ├── Makefile.am ├── dos_assert.h ├── fatal_assert.h ├── locale_utils.cc ├── locale_utils.h ├── logger.cc ├── logger.h ├── pty_compat.cc ├── pty_compat.h ├── select.cc ├── select.h ├── swrite.cc ├── swrite.h ├── timestamp.cc ├── timestamp.h └── utils.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.o 3 | *.pb.cc 4 | *.pb.h 5 | .deps 6 | Makefile 7 | Makefile.in 8 | .cproject 9 | .project 10 | 11 | /INSTALL 12 | /aclocal.m4 13 | /ar-lib 14 | /autom4te.cache 15 | /compile 16 | /config.h 17 | /config.h.in 18 | /config.h.in~ 19 | /config.log 20 | /config.status 21 | /configure 22 | /depcomp 23 | /install-sh 24 | /missing 25 | /mosh-*.tar.gz 26 | /stamp-h1 27 | /test-driver 28 | /VERSION 29 | /scripts/mosh 30 | /version.h 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: false 3 | 4 | addons: 5 | apt: 6 | packages: 7 | - protobuf-compiler 8 | - libprotobuf-dev 9 | - libutempter-dev 10 | 11 | before_install: 12 | - git fetch --tags --unshallow 13 | 14 | script: 15 | - ./autogen.sh 16 | - ./configure --enable-compile-warnings=error --enable-examples 17 | - make distcheck 18 | -------------------------------------------------------------------------------- /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 | ACLOCAL_AMFLAGS = -I m4 2 | SUBDIRS = src scripts man conf 3 | EXTRA_DIST = autogen.sh ocb-license.html README.md COPYING.iOS 4 | BUILT_SOURCES = version.h 5 | CLANG_SCAN_BUILD = scan-build 6 | AM_DISTCHECK_CONFIGURE_FLAGS = --enable-compile-warnings=error --enable-examples 7 | 8 | .PHONY: VERSION 9 | 10 | VERSION: 11 | @echo @PACKAGE_STRING@ > VERSION.dist 12 | @set -e; if git describe --dirty --always > VERSION.git 2>&1 && \ 13 | [ -z `git rev-parse --show-prefix` ]; then \ 14 | if ! diff -q VERSION.git VERSION > /dev/null 2>&1; then \ 15 | mv -f VERSION.git VERSION; \ 16 | fi; \ 17 | elif ! diff -q VERSION.dist VERSION > /dev/null 2>&1; then \ 18 | mv -f VERSION.dist VERSION; \ 19 | fi 20 | @rm -f VERSION.dist VERSION.git 21 | 22 | version.h: VERSION 23 | @printf '#define BUILD_VERSION "%s"\n' "$$(cat VERSION)" > version.h.new 24 | @set -e; if ! diff -q version.h version.h.new > /dev/null 2>&1; then \ 25 | mv -f version.h.new version.h; \ 26 | fi 27 | @rm -f version.h.new 28 | 29 | clean-local: 30 | @rm -rf version.h VERSION cov-int mosh-coverity.txz 31 | 32 | cppcheck: $(BUILT_SOURCES) config.h 33 | cppcheck --enable=all --template=gcc -include config.h -I . \ 34 | -I src/crypto -I src/frontend -I src/network -I src/protobufs \ 35 | -I src/statesync -I src/terminal -I src/util \ 36 | -I /usr/include -I /usr/include/google/protobuf -I/usr/include/openssl \ 37 | . 38 | 39 | cov-build: $(BUILT_SOURCES) config.h 40 | $(MAKE) clean && rm -rf cov-int && \ 41 | cov-build --dir cov-int $(MAKE) check && \ 42 | tar -caf mosh-coverity.txz cov-int 43 | 44 | scan-build: $(BUILT_SOURCES) config.h 45 | $(MAKE) clean && $(CLANG_SCAN_BUILD) $(MAKE) check 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec autoreconf -fi 4 | -------------------------------------------------------------------------------- /build-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | git-buildpackage --git-upstream-branch=master --git-upstream-tree=branch 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 | _mosh () { 2 | local cur prev 3 | 4 | _init_completion || return 5 | 6 | _known_hosts_real -a "$cur" 7 | } 8 | 9 | complete -F _mosh mosh 10 | -------------------------------------------------------------------------------- /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/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: mosh 2 | Section: net 3 | Priority: optional 4 | Maintainer: Keith Winstein 5 | Build-Depends: debhelper (>= 7.0.50), autotools-dev, protobuf-compiler, libprotobuf-dev, dh-autoreconf, pkg-config, libutempter-dev, zlib1g-dev, libncurses5-dev, libssl-dev, bash-completion 6 | Standards-Version: 3.9.6.1 7 | Homepage: http://mosh.mit.edu 8 | Vcs-Git: git://github.com/keithw/mosh.git 9 | Vcs-Browser: https://github.com/keithw/mosh 10 | 11 | Package: mosh 12 | Architecture: any 13 | Pre-Depends: dpkg (>= 1.15.7.2) 14 | Depends: ${shlibs:Depends}, ${misc:Depends}, openssh-client 15 | Recommends: libio-socket-ip-perl 16 | Description: Mobile shell that supports roaming and intelligent local echo 17 | Mosh is a remote terminal application that supports: 18 | - intermittent network connectivity, 19 | - roaming to different IP address without dropping the connection, and 20 | - intelligent local echo and line editing to reduce the effects 21 | of "network lag" on high-latency connections. 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | https://github.com/keithw/mosh/tags .*/mosh-(\d[\d\.]+)\.tar\.gz 3 | -------------------------------------------------------------------------------- /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: http://mosh.mit.edu/ 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_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_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 | -------------------------------------------------------------------------------- /macosx/.gitignore: -------------------------------------------------------------------------------- 1 | /mosh-package.pmdoc 2 | /Mosh*.pkg 3 | /prefix 4 | -------------------------------------------------------------------------------- /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/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # This script is known to work on: 5 | # OS X 10.5.8, Xcode 3.1.2, SDK 10.5, MacPorts 2.3.3 6 | # OS X 10.9.5, Xcode 5.1.1, SDK 10.9, MacPorts 2.3.2 7 | # OS X 10.10.3, XCode 6.3.2, SDK 10.10, Homebrew 0.9.5/8da6986 8 | # 9 | # You may need to set PATH to include the location of your 10 | # PackageMaker binary, if your system is old enough to need that. 11 | # Setting MACOSX_DEPLOYMENT_TARGET will select an SDK as usual. 12 | # 13 | # If you are using Homebrew, you should install protobuf (and any 14 | # other future Homebrew dependencies) with 15 | # `--universal --build-bottle`. 16 | # The first option should be fairly obvious; the second has the side 17 | # effect of disabling Homebrew's overzealous processor optimization 18 | # with (effectively) `-march=native`. 19 | # 20 | 21 | set -e 22 | 23 | protobuf_LIBS=$(l=libprotobuf.a; for i in /opt/local/lib /usr/local/lib; do if [ -f $i/$l ]; then echo $i/$l; fi; done) 24 | if [ -z "$protobuf_LIBS" ]; then echo "Can't find libprotobuf.a"; exit 1; fi 25 | export protobuf_LIBS 26 | if ! pkg-config --cflags protobuf > /dev/null 2>&1; then 27 | protobuf_CFLAGS=-I$(for i in /opt /usr; do d=$i/local/include; if [ -d $d/google/protobuf ]; then echo $d; fi; done) 28 | if [ "$protobuf_CFLAGS" = "-I" ]; then echo "Can't find protobuf includes"; exit 1; fi 29 | export protobuf_CFLAGS 30 | fi 31 | 32 | echo "Building into prefix..." 33 | 34 | 35 | # 36 | # XXX This script abuses Configure's --prefix argument badly. It uses 37 | # it as a $DESTDIR, but --prefix can also affect paths in generated 38 | # objects. That is not *currently* a problem in mosh. 39 | # 40 | PREFIX="$(pwd)/prefix" 41 | 42 | ARCHS=" ppc ppc64 i386 x86_64" 43 | 44 | pushd .. > /dev/null 45 | 46 | if [ ! -f configure ]; 47 | then 48 | echo "Running autogen." 49 | PATH=/opt/local/bin:$PATH ./autogen.sh 50 | fi 51 | 52 | # 53 | # Build archs one by one. 54 | # 55 | for arch in $ARCHS; do 56 | echo "Building for ${arch}..." 57 | prefix="${PREFIX}_${arch}" 58 | rm -rf "${prefix}" 59 | mkdir "${prefix}" 60 | if ./configure --prefix="${prefix}/local" \ 61 | CC="cc -arch ${arch}" CPP="cc -arch ${arch} -E" CXX="c++ -arch ${arch}" \ 62 | TINFO_LIBS=-lncurses \ 63 | OPENSSL_CFLAGS=" " OPENSSL_LIBS="-lssl -lcrypto -lz" && 64 | make clean && 65 | make install -j8 && 66 | rm -f "${prefix}/etc" 67 | then 68 | # mosh-client built with Xcode 3.1.2 bus-errors if the binary is stripped. 69 | # strip "${prefix}/local/bin/mosh-client" "${prefix}/local/bin/mosh-server" 70 | BUILT_ARCHS="$BUILT_ARCHS $arch" 71 | fi 72 | done 73 | 74 | if [ -z "$BUILT_ARCHS" ]; then 75 | echo "No architectures built successfully" 76 | exit 1 77 | fi 78 | 79 | echo "Building universal binaries for archs ${BUILT_ARCHS}..." 80 | 81 | 82 | rm -rf "$PREFIX" 83 | # Copy one architecture to get all files into place. 84 | for arch in $BUILT_ARCHS; do 85 | cp -Rp "${PREFIX}_${arch}" "${PREFIX}" 86 | break 87 | done 88 | 89 | # Build fat binaries 90 | # XXX will break with spaces in pathname 91 | for prog in local/bin/mosh-client local/bin/mosh-server; do 92 | archprogs= 93 | for arch in $BUILT_ARCHS; do 94 | archprogs="$archprogs ${PREFIX}_${arch}/$prog" 95 | done 96 | lipo -create $archprogs -output "${PREFIX}/$prog" 97 | done 98 | 99 | perl -wlpi -e 's{#!/usr/bin/env perl}{#!/usr/bin/perl}' "$PREFIX/local/bin/mosh" 100 | 101 | popd > /dev/null 102 | 103 | PACKAGE_VERSION=$(cat ../VERSION) 104 | 105 | OUTFILE="$PACKAGE_VERSION.pkg" 106 | 107 | rm -f "$OUTFILE" 108 | 109 | if which -s pkgbuild; then 110 | # To replace PackageMaker, you: 111 | # * make a bare package with the build products 112 | # * essentially take the Distribution file that PackageMaker generated and 113 | # use it as the --distribution input file for productbuild 114 | echo "Preprocessing package description..." 115 | PKGID=edu.mit.mosh.mosh.pkg 116 | for file in Distribution; do 117 | sed -e "s/@PACKAGE_VERSION@/${PACKAGE_VERSION}/g" ${file}.in > ${file} 118 | done 119 | echo "Running pkgbuild/productbuild..." 120 | mkdir -p Resources/en.lproj 121 | cp -p copying.rtf Resources/en.lproj/License 122 | cp -p readme.rtf Resources/en.lproj/Readme 123 | pkgbuild --root "$PREFIX" --identifier $PKGID $PKGID 124 | productbuild --distribution Distribution \ 125 | --resources Resources \ 126 | --package-path . \ 127 | "$OUTFILE" 128 | echo "Cleaning up..." 129 | rm -rf $PKGID 130 | else 131 | echo "Preprocessing package description..." 132 | INDIR=mosh-package.pmdoc.in 133 | OUTDIR=mosh-package.pmdoc 134 | mkdir -p "$OUTDIR" 135 | pushd "$INDIR" > /dev/null 136 | for file in * 137 | do 138 | sed -e 's/$PACKAGE_VERSION/'"$PACKAGE_VERSION"'/g' "$file" > "../$OUTDIR/$file" 139 | done 140 | popd > /dev/null 141 | echo "Running PackageMaker..." 142 | env PATH="/Applications/PackageMaker.app/Contents/MacOS:/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS:$PATH" PackageMaker -d mosh-package.pmdoc -o "$OUTFILE" -i edu.mit.mosh.mosh.pkg 143 | echo "Cleaning up..." 144 | rm -rf "$OUTDIR" 145 | fi 146 | 147 | 148 | if [ -f "$OUTFILE" ]; 149 | then 150 | echo "Successfully built $OUTFILE with archs ${BUILT_ARCHS}." 151 | else 152 | echo "There was an error building $OUTFILE." 153 | false 154 | fi 155 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | IP PORT 24 | [\-w] 25 | [\-f \fILOGFILE\fP] 26 | [\-d \fIDEBUG-LEVEL\fP] 27 | [\-m \fILOSS-TOLERANCE\fP] 28 | .br 29 | .B mosh-client 30 | \-c 31 | .br 32 | .SH DESCRIPTION 33 | \fBmosh-client\fP is a helper program for the 34 | .BR mosh (1) 35 | remote terminal application. 36 | 37 | \fBmosh\fP itself is a setup script that establishes an SSH 38 | connection, runs the server-side helper \fBmosh-server\fP, 39 | and collects the server's port number and session key. 40 | 41 | \fBmosh\fP then executes \fBmosh-client\fP with the server's IP 42 | address, port, and session key. \fBmosh-client\fP runs for 43 | the lifetime of the connection. 44 | 45 | The 22-byte base64 session key given by \fBmosh-server\fP is supplied 46 | in the MOSH_KEY environment variable. This represents a 128-bit AES 47 | key that protects the integrity and confidentiality of the session. 48 | 49 | For constructing new setup wrappers for remote execution facilities 50 | other than SSH, it may be necessary to invoke \fBmosh-client\fP 51 | directly. 52 | 53 | With the \-c option, \fBmosh-client\fP instead prints the number of colors 54 | of the terminal given by the TERM environment variable. 55 | 56 | With the \-w option, \fBmosh-client\fP prints its PID at launch and 57 | waits until the user press ENTER. This allow the user to easily 58 | attach a gdb session. 59 | 60 | The \-f option specify the log file, and the \-d option the debug 61 | level. There is two debug level: \fBerror\fP and \fBdebug\fP. By 62 | default, there is no log output. 63 | 64 | The \-m option specify the loss ratio tolerance: packets sent will be duplicate 65 | on each different path until the product of the loss ratio of the used paths is 66 | less than the tolerance (or no more different paths are available). The default 67 | is 0. 68 | 69 | .SH ENVIRONMENT VARIABLES 70 | 71 | .TP 72 | .B MOSH_KEY 73 | This variable must be set, and must contain a Base64-encoded cryptographic key from 74 | .BR mosh-server (1). 75 | 76 | .TP 77 | .B MOSH_ESCAPE_KEY 78 | See 79 | .BR mosh (1). 80 | 81 | .TP 82 | .B MOSH_PREDICTION_DISPLAY 83 | Controls local echo as described in 84 | .BR mosh (1). 85 | 86 | .TP 87 | .B MOSH_TITLE_NOPREFIX 88 | See 89 | .BR mosh (1). 90 | 91 | 92 | .SH SEE ALSO 93 | .BR mosh (1), 94 | .BR mosh-server (1). 95 | 96 | Project home page: 97 | .I http://mosh.mit.edu 98 | 99 | .br 100 | .SH AUTHOR 101 | mosh was written by Keith Winstein . 102 | .SH BUGS 103 | Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe 104 | to the 105 | .nh 106 | .I mosh-users@mit.edu 107 | .hy 108 | mailing list, at 109 | .br 110 | .nh 111 | .I http://mailman.mit.edu/mailman/listinfo/mosh-users 112 | .hy 113 | . 114 | -------------------------------------------------------------------------------- /man/mosh-server.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 "October 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-server \- server-side helper for mosh 20 | .SH SYNOPSIS 21 | .B mosh-server 22 | new 23 | [\-s] 24 | [\-v] 25 | [\-i \fIIP\fP] 26 | [\-p \fIPORT\fP[:\fIPORT2\fP]] 27 | [\-c \fICOLORS\fP] 28 | [\-f \fILOGFILE\fP] 29 | [\-d \fIDEBUG-LEVEL\fP] 30 | [\-m \fILOSS-TOLERANCE\fP] 31 | [\-\- command...] 32 | .br 33 | .B mosh-server 34 | new 35 | \-e 36 | .br 37 | .SH DESCRIPTION 38 | \fBmosh-server\fP is a helper program for the 39 | .BR mosh(1) 40 | remote terminal application. 41 | 42 | \fBmosh-server\fP binds to a high UDP port and chooses an encryption 43 | key to protect the session. It prints both on standard output, 44 | detaches from the terminal, and waits for the \fBmosh-client\fP to 45 | establish a connection. It will exit if no client has contacted 46 | it within 60 seconds. 47 | 48 | By default, \fBmosh-server\fP binds to a port between 60000 and 49 | 61000 and executes the user's login shell. 50 | 51 | On platforms with \fButempter\fP, \fBmosh-server\fP maintains an entry 52 | in the 53 | .BR utmp(5) 54 | file to indicate its process ID, whether the session is connected, 55 | and the client's current IP address. 56 | 57 | \fBmosh-server\fP exits when the client terminates the connection. 58 | 59 | .SH OPTIONS 60 | 61 | The argument "new" must be first on the command line to use 62 | command-line options. 63 | 64 | .TP 65 | .B \-s 66 | bind to the local interface used for an incoming SSH connection, given 67 | in the \fBSSH_CONNECTION\fP environment variable (for multihomed 68 | hosts) 69 | 70 | .TP 71 | .B \-v 72 | Print some debugging information even after detaching. 73 | 74 | .TP 75 | .B \-i \fIIP\fP 76 | IP address of the local interface to bind (for multihomed hosts) 77 | 78 | .TP 79 | .B \-p \fIPORT\fP[:\fIPORT2\fP] 80 | UDP port number or port-range to bind 81 | 82 | .TP 83 | .B \-c \fICOLORS\fP 84 | Number of colors to advertise to applications through TERM (e.g. 8, 256) 85 | 86 | .TP 87 | .B \-l \fINAME=VALUE\fP 88 | Locale-related environment variable to try as part of a fallback 89 | environment, if the startup environment does not specify a character 90 | set of UTF-8. 91 | 92 | .TP 93 | .B \-a 94 | Keep the server attached to the shell. 95 | 96 | .TP 97 | .B \-f \fIFILENAME\fP 98 | Specify the log file. By default, there is no log output. 99 | 100 | .TP 101 | .B \-d \fIDEBUG-LEVEL\fP 102 | Specify the debug level: either \fBerror\fP or \fBdebug\fP. By default, there 103 | is no log output. 104 | 105 | .TP 106 | .B \-m \fILOSS-RATIO-TOLERANCE\fP 107 | This option control the packet duplication algorithm: packets sent will be 108 | duplicate on each different path until the product of the loss ratio of the used 109 | paths is less than the tolerance (or no more different paths are available). 110 | The default is 0. 111 | 112 | .TP 113 | .B \-e 114 | Print the supported extensions, and exit. The format is standard and can be 115 | parsed. It begins by one header line with the package name and the build 116 | version, followed by multiple lines having each the name and the supported 117 | options of an extension. 118 | 119 | .SH EXAMPLE 120 | 121 | .nf 122 | $ mosh-server 123 | 124 | MOSH CONNECT 60001 UAkFedSsVJs2LfMeKyQB5g 125 | 126 | mosh-server (mosh 1.1) 127 | [...] (copyright notice omitted) 128 | 129 | [mosh-server detached, pid = 20443] 130 | .fi 131 | 132 | .SH SEE ALSO 133 | .BR mosh (1), 134 | .BR mosh-client (1). 135 | 136 | Project home page: 137 | .I http://mosh.mit.edu 138 | 139 | .br 140 | .SH AUTHOR 141 | mosh was written by Keith Winstein . 142 | .SH BUGS 143 | Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe 144 | to the 145 | .nh 146 | .I mosh-users@mit.edu 147 | .hy 148 | mailing list, at 149 | .br 150 | .nh 151 | .I http://mailman.mit.edu/mailman/listinfo/mosh-users 152 | .hy 153 | . 154 | -------------------------------------------------------------------------------- /my_configure.sh: -------------------------------------------------------------------------------- 1 | PKG_CONFIG_PATH='/usr/local/lib/pkgconfig:/usr/lib/pkgconfig' ./configure CFLAGS='-g -Wall -O0' CXXFLAGS='-g -Wall -O0' 2 | -------------------------------------------------------------------------------- /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 Makefile 8 | @sed -e "s/\@VERSION\@/`cat ../VERSION`/" -e "s/\@PACKAGE_STRING\@/@PACKAGE_STRING@/" $(srcdir)/mosh.pl > mosh 9 | @chmod a+x mosh 10 | -------------------------------------------------------------------------------- /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 $CC, $CXX, $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 = protobufs util crypto terminal network statesync frontend examples tests 2 | -------------------------------------------------------------------------------- /src/crypto/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(srcdir)/../util $(OPENSSL_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshcrypto.a 5 | 6 | OCB_SRCS = \ 7 | ae.h \ 8 | ocb.cc 9 | 10 | libmoshcrypto_a_SOURCES = \ 11 | $(OCB_SRCS) \ 12 | base64.cc \ 13 | base64.h \ 14 | byteorder.h \ 15 | crypto.cc \ 16 | crypto.h \ 17 | prng.h 18 | -------------------------------------------------------------------------------- /src/crypto/base64.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 "fatal_assert.h" 38 | #include "base64.h" 39 | 40 | bool base64_decode( const char *b64, const size_t b64_len, 41 | char *raw, size_t *raw_len ) 42 | { 43 | bool ret = false; 44 | 45 | fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */ 46 | fatal_assert( *raw_len == 16 ); 47 | 48 | /* initialize input/output */ 49 | BIO_METHOD *b64_method = BIO_f_base64(); 50 | fatal_assert( b64_method ); 51 | 52 | BIO *b64_bio = BIO_new( b64_method ); 53 | fatal_assert( b64_bio ); 54 | 55 | BIO_set_flags( b64_bio, BIO_FLAGS_BASE64_NO_NL ); 56 | 57 | BIO *mem_bio = BIO_new_mem_buf( (void *) b64, b64_len ); 58 | fatal_assert( mem_bio ); 59 | 60 | BIO *combined_bio = BIO_push( b64_bio, mem_bio ); 61 | fatal_assert( combined_bio ); 62 | 63 | fatal_assert( 1 == BIO_flush( combined_bio ) ); 64 | 65 | /* read the string */ 66 | int bytes_read = BIO_read( combined_bio, raw, *raw_len ); 67 | if ( bytes_read <= 0 ) { 68 | goto end; 69 | } 70 | 71 | if ( bytes_read != (int)*raw_len ) { 72 | goto end; 73 | } 74 | 75 | fatal_assert( 1 == BIO_flush( combined_bio ) ); 76 | 77 | /* check if there is more to read */ 78 | char extra[ 256 ]; 79 | bytes_read = BIO_read( combined_bio, extra, 256 ); 80 | if ( bytes_read > 0 ) { 81 | goto end; 82 | } 83 | 84 | /* check if mem buf is empty */ 85 | if ( !BIO_eof( mem_bio ) ) { 86 | goto end; 87 | } 88 | 89 | ret = true; 90 | end: 91 | BIO_free_all( combined_bio ); 92 | return ret; 93 | } 94 | 95 | void base64_encode( const char *raw, const size_t raw_len, 96 | char *b64, const size_t b64_len ) 97 | { 98 | fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */ 99 | fatal_assert( raw_len == 16 ); 100 | 101 | /* initialize input/output */ 102 | BIO_METHOD *b64_method = BIO_f_base64(), *mem_method = BIO_s_mem(); 103 | fatal_assert( b64_method ); 104 | fatal_assert( mem_method ); 105 | 106 | BIO *b64_bio = BIO_new( b64_method ), *mem_bio = BIO_new( mem_method ); 107 | fatal_assert( b64_bio ); 108 | fatal_assert( mem_bio ); 109 | 110 | BIO_set_flags( b64_bio, BIO_FLAGS_BASE64_NO_NL ); 111 | 112 | BIO *combined_bio = BIO_push( b64_bio, mem_bio ); 113 | fatal_assert( combined_bio ); 114 | 115 | /* write the string */ 116 | int bytes_written = BIO_write( combined_bio, raw, raw_len ); 117 | fatal_assert( bytes_written >= 0 ); 118 | 119 | fatal_assert( bytes_written == (int)raw_len ); 120 | 121 | fatal_assert( 1 == BIO_flush( combined_bio ) ); 122 | 123 | /* check if mem buf has desired length */ 124 | fatal_assert( BIO_pending( mem_bio ) == (int)b64_len ); 125 | 126 | char *mem_ptr; 127 | 128 | BIO_get_mem_data( mem_bio, &mem_ptr ); 129 | 130 | memcpy( b64, mem_ptr, b64_len ); 131 | 132 | BIO_free_all( combined_bio ); 133 | } 134 | -------------------------------------------------------------------------------- /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 | bool base64_decode( const char *b64, const size_t b64_len, 34 | char *raw, size_t *raw_len ); 35 | 36 | void base64_encode( const char *raw, const size_t raw_len, 37 | 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 "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 | uint8_t xs[ 8 ] = { 75 | ( x >> 56 ) & 0xFF, 76 | ( x >> 48 ) & 0xFF, 77 | ( x >> 40 ) & 0xFF, 78 | ( x >> 32 ) & 0xFF, 79 | ( x >> 24 ) & 0xFF, 80 | ( x >> 16 ) & 0xFF, 81 | ( x >> 8 ) & 0xFF, 82 | 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 | union { 93 | const uint8_t *p8; 94 | const uint64_t *p64; 95 | } u; 96 | u.p64 = &x; 97 | return ( uint64_t( u.p8[ 0 ] ) << 56 ) 98 | | ( uint64_t( u.p8[ 1 ] ) << 48 ) 99 | | ( uint64_t( u.p8[ 2 ] ) << 40 ) 100 | | ( uint64_t( u.p8[ 3 ] ) << 32 ) 101 | | ( uint64_t( u.p8[ 4 ] ) << 24 ) 102 | | ( uint64_t( u.p8[ 5 ] ) << 16 ) 103 | | ( uint64_t( u.p8[ 6 ] ) << 8 ) 104 | | ( uint64_t( u.p8[ 7 ] ) ); 105 | } 106 | 107 | inline uint16_t htobe16( uint16_t x ) { 108 | uint8_t xs[ 2 ] = { 109 | ( x >> 8 ) & 0xFF, 110 | x & 0xFF }; 111 | union { 112 | const uint8_t *p8; 113 | const uint16_t *p16; 114 | } u; 115 | u.p8 = xs; 116 | return *u.p16; 117 | } 118 | 119 | inline uint16_t be16toh( uint16_t x ) { 120 | union { 121 | const uint8_t *p8; 122 | const uint16_t *p16; 123 | } u; 124 | u.p16 = &x; 125 | return ( uint16_t( u.p8[ 0 ] ) << 8 ) 126 | | ( uint16_t( u.p8[ 1 ] ) ); 127 | } 128 | 129 | #endif 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /src/crypto/crypto.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 CRYPTO_HPP 34 | #define CRYPTO_HPP 35 | 36 | #include "ae.h" 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | using std::string; 44 | 45 | long int myatoi( const char *str ); 46 | 47 | namespace Crypto { 48 | class CryptoException : public std::exception { 49 | public: 50 | string text; 51 | bool fatal; 52 | CryptoException( string s_text, bool s_fatal = false ) 53 | : text( s_text ), fatal( s_fatal ) {}; 54 | const char *what() const throw () { return text.c_str(); } 55 | ~CryptoException() throw () {} 56 | }; 57 | 58 | /* 16-byte-aligned buffer, with length. */ 59 | class AlignedBuffer { 60 | private: 61 | size_t m_len; 62 | void *m_allocated; 63 | char *m_data; 64 | 65 | public: 66 | AlignedBuffer( size_t len, const char *data = NULL ); 67 | 68 | ~AlignedBuffer() { 69 | free( m_allocated ); 70 | } 71 | 72 | char * data( void ) const { return m_data; } 73 | size_t len( void ) const { return m_len; } 74 | 75 | private: 76 | /* Not implemented */ 77 | AlignedBuffer( const AlignedBuffer & ); 78 | AlignedBuffer & operator=( const AlignedBuffer & ); 79 | }; 80 | 81 | class Base64Key { 82 | private: 83 | unsigned char key[ 16 ]; 84 | 85 | public: 86 | Base64Key(); /* random key */ 87 | Base64Key( string printable_key ); 88 | string printable_key( void ) const; 89 | unsigned char *data( void ) { return key; } 90 | }; 91 | 92 | class Nonce { 93 | public: 94 | static const int NONCE_LEN = 12; 95 | 96 | private: 97 | char bytes[ NONCE_LEN ]; 98 | 99 | public: 100 | Nonce( uint64_t val ); 101 | Nonce( char *s_bytes, size_t len ); 102 | 103 | string cc_str( void ) const { return string( bytes + 4, 8 ); } 104 | const char *data( void ) const { return bytes; } 105 | uint64_t val( void ); 106 | }; 107 | 108 | class Message { 109 | public: 110 | Nonce nonce; 111 | string text; 112 | 113 | Message( char *nonce_bytes, size_t nonce_len, 114 | char *text_bytes, size_t text_len ); 115 | Message( Nonce s_nonce, string s_text ); 116 | }; 117 | 118 | class Session { 119 | private: 120 | Base64Key key; 121 | AlignedBuffer ctx_buf; 122 | ae_ctx *ctx; 123 | uint64_t blocks_encrypted; 124 | 125 | AlignedBuffer plaintext_buffer; 126 | AlignedBuffer ciphertext_buffer; 127 | AlignedBuffer nonce_buffer; 128 | 129 | public: 130 | static const int RECEIVE_MTU = 2048; 131 | 132 | Session( Base64Key s_key ); 133 | ~Session(); 134 | 135 | string encrypt( Message plaintext ); 136 | Message decrypt( string ciphertext ); 137 | 138 | Session( const Session & ); 139 | Session & operator=( const Session & ); 140 | }; 141 | 142 | void disable_dumping_core( void ); 143 | void reenable_dumping_core( void ); 144 | } 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /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 "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 | private: 52 | std::ifstream randfile; 53 | 54 | /* unimplemented to satisfy -Weffc++ */ 55 | PRNG( const PRNG & ); 56 | PRNG & operator=( const PRNG & ); 57 | 58 | public: 59 | PRNG() : randfile( rdev, std::ifstream::in | std::ifstream::binary ) {} 60 | 61 | void fill( void *dest, size_t size ) { 62 | if ( 0 == size ) { 63 | return; 64 | } 65 | 66 | randfile.read( static_cast( dest ), size ); 67 | if ( !randfile ) { 68 | throw CryptoException( "Could not read from " + std::string( rdev ) ); 69 | } 70 | } 71 | 72 | uint8_t uint8() { 73 | uint8_t x; 74 | fill( &x, 1 ); 75 | return x; 76 | } 77 | 78 | uint32_t uint32() { 79 | uint32_t x; 80 | fill( &x, 4 ); 81 | return x; 82 | } 83 | 84 | uint64_t uint64() { 85 | uint64_t x; 86 | fill( &x, 8 ); 87 | return x; 88 | } 89 | }; 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/examples/.gitignore: -------------------------------------------------------------------------------- 1 | /decrypt 2 | /encrypt 3 | /ntester 4 | /parse 5 | /termemu 6 | /benchmark 7 | -------------------------------------------------------------------------------- /src/examples/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = $(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 $(OPENSSL_LIBS) 11 | 12 | decrypt_SOURCES = decrypt.cc 13 | decrypt_CPPFLAGS = -I$(srcdir)/../crypto 14 | decrypt_LDADD = ../crypto/libmoshcrypto.a $(OPENSSL_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 $(LIBUTIL) 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 $(LIBUTIL) $(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 $(LIBUTIL) -lm $(protobuf_LIBS) $(OPENSSL_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) $(LIBUTIL) -lm $(TINFO_LIBS) $(protobuf_LIBS) $(OPENSSL_LIBS) 31 | -------------------------------------------------------------------------------- /src/examples/benchmark.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 "config.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #if HAVE_PTY_H 50 | #include 51 | #elif HAVE_UTIL_H 52 | #include 53 | #endif 54 | 55 | #include "swrite.h" 56 | #include "completeterminal.h" 57 | #include "user.h" 58 | #include "terminaloverlay.h" 59 | #include "locale_utils.h" 60 | #include "fatal_assert.h" 61 | 62 | const int ITERATIONS = 100000; 63 | 64 | using namespace Terminal; 65 | 66 | int main( int argc, char **argv ) 67 | { 68 | try { 69 | int fbmod = 0; 70 | int width = 80, height = 24; 71 | int iterations = ITERATIONS; 72 | if (argc > 1) { 73 | iterations = atoi(argv[1]); 74 | if (iterations < 1 || iterations > 1000000000) { 75 | fprintf(stderr, "bogus iteration count\n"); 76 | exit(1); 77 | } 78 | } 79 | if (argc > 3) { 80 | width = atoi(argv[2]); 81 | height = atoi(argv[3]); 82 | if (width < 1 || width > 1000 || height < 1 || height > 1000) { 83 | fprintf(stderr, "bogus window size\n"); 84 | exit(1); 85 | } 86 | } 87 | Framebuffer local_framebuffers[ 2 ] = { Framebuffer(width,height), Framebuffer(width,height) }; 88 | Framebuffer *local_framebuffer = &(local_framebuffers[ fbmod ]); 89 | Framebuffer *new_state = &(local_framebuffers[ !fbmod ]); 90 | Overlay::OverlayManager overlays; 91 | Display display( true ); 92 | Complete local_terminal( width, height ); 93 | 94 | /* Adopt native locale */ 95 | set_native_locale(); 96 | fatal_assert( is_utf8_locale() ); 97 | 98 | for ( int i = 0; i < iterations; i++ ) { 99 | /* type a character */ 100 | overlays.get_prediction_engine().new_user_byte( i + 'x', *local_framebuffer ); 101 | 102 | /* fetch target state */ 103 | *new_state = local_terminal.get_fb(); 104 | 105 | /* apply local overlays */ 106 | overlays.apply( *new_state ); 107 | 108 | /* calculate minimal difference from where we are */ 109 | const string diff( display.new_frame( false, 110 | *local_framebuffer, 111 | *new_state ) ); 112 | 113 | /* make sure to use diff */ 114 | if ( diff.size() > INT_MAX ) { 115 | exit( 1 ); 116 | } 117 | 118 | fbmod = !fbmod; 119 | local_framebuffer = &(local_framebuffers[ fbmod ]); 120 | new_state = &(local_framebuffers[ !fbmod ]); 121 | } 122 | } catch ( const std::exception &e ) { 123 | fprintf( stderr, "Exception caught: %s\n", e.what() ); 124 | return 1; 125 | } 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /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 "crypto.h" 38 | 39 | using namespace Crypto; 40 | using namespace std; 41 | 42 | int main( int argc, char *argv[] ) 43 | { 44 | if ( argc != 2 ) { 45 | fprintf( stderr, "Usage: %s KEY\n", argv[ 0 ] ); 46 | return 1; 47 | } 48 | 49 | try { 50 | Base64Key key( argv[ 1 ] ); 51 | Session session( key ); 52 | 53 | /* Read input */ 54 | ostringstream input; 55 | input << cin.rdbuf(); 56 | 57 | /* Decrypt message */ 58 | 59 | Message message = session.decrypt( input.str() ); 60 | 61 | fprintf( stderr, "Nonce = %ld\n", 62 | (long)message.nonce.val() ); 63 | cout << message.text; 64 | } catch ( const CryptoException &e ) { 65 | cerr << e.what() << endl; 66 | exit( 1 ); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /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 "crypto.h" 38 | 39 | using namespace Crypto; 40 | using namespace std; 41 | 42 | int main( int argc, char *argv[] ) 43 | { 44 | if ( argc != 2 ) { 45 | fprintf( stderr, "Usage: %s NONCE\n", argv[ 0 ] ); 46 | return 1; 47 | } 48 | 49 | try { 50 | Base64Key key; 51 | Session session( key ); 52 | Nonce nonce( myatoi( argv[ 1 ] ) ); 53 | 54 | /* Read input */ 55 | ostringstream input; 56 | input << cin.rdbuf(); 57 | 58 | /* Encrypt message */ 59 | 60 | string ciphertext = session.encrypt( Message( nonce, input.str() ) ); 61 | 62 | cerr << "Key: " << key.printable_key() << endl; 63 | 64 | cout << ciphertext; 65 | } catch ( const CryptoException &e ) { 66 | cerr << e.what() << endl; 67 | exit( 1 ); 68 | } 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/examples/ntester.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 "user.h" 37 | #include "fatal_assert.h" 38 | #include "pty_compat.h" 39 | #include "networktransport.cc" 40 | #include "select.h" 41 | 42 | using namespace Network; 43 | 44 | int main( int argc, char *argv[] ) 45 | { 46 | bool server = true; 47 | char *key; 48 | char *ip; 49 | char *port; 50 | 51 | UserStream me, remote; 52 | 53 | Transport *n; 54 | 55 | try { 56 | if ( argc > 1 ) { 57 | server = false; 58 | /* client */ 59 | 60 | key = argv[ 1 ]; 61 | ip = argv[ 2 ]; 62 | port = argv[ 3 ]; 63 | 64 | n = new Transport( me, remote, key, ip, port ); 65 | } else { 66 | n = new Transport( me, remote, NULL, NULL ); 67 | } 68 | fprintf( stderr, "Port bound is %s, key is %s\n", n->port().c_str(), n->get_key().c_str() ); 69 | } catch ( const std::exception &e ) { 70 | fprintf( stderr, "Fatal startup error: %s\n", e.what() ); 71 | exit( 1 ); 72 | } 73 | 74 | if ( server ) { 75 | Select &sel = Select::get_instance(); 76 | uint64_t last_num = n->get_remote_state_num(); 77 | while ( true ) { 78 | try { 79 | sel.clear_fds(); 80 | std::vector< int > fd_list( n->fds() ); 81 | assert( fd_list.size() == 1 ); /* servers don't hop */ 82 | int network_fd = fd_list.back(); 83 | sel.add_fd( network_fd ); 84 | if ( sel.select( n->wait_time() ) < 0 ) { 85 | perror( "select" ); 86 | exit( 1 ); 87 | } 88 | 89 | n->tick(); 90 | 91 | if ( sel.read( network_fd ) ) { 92 | n->recv(); 93 | 94 | if ( n->get_remote_state_num() != last_num ) { 95 | fprintf( stderr, "[%d=>%d %s]", (int)last_num, (int)n->get_remote_state_num(), n->get_remote_diff().c_str() ); 96 | last_num = n->get_remote_state_num(); 97 | } 98 | } 99 | } catch ( const std::exception &e ) { 100 | fprintf( stderr, "Server error: %s\n", e.what() ); 101 | } 102 | } 103 | } else { 104 | struct termios saved_termios; 105 | struct termios the_termios; 106 | 107 | if ( tcgetattr( STDIN_FILENO, &the_termios ) < 0 ) { 108 | perror( "tcgetattr" ); 109 | exit( 1 ); 110 | } 111 | 112 | saved_termios = the_termios; 113 | 114 | cfmakeraw( &the_termios ); 115 | 116 | if ( tcsetattr( STDIN_FILENO, TCSANOW, &the_termios ) < 0 ) { 117 | perror( "tcsetattr" ); 118 | exit( 1 ); 119 | } 120 | 121 | Select &sel = Select::get_instance(); 122 | 123 | while( true ) { 124 | sel.clear_fds(); 125 | sel.add_fd( STDIN_FILENO ); 126 | 127 | std::vector< int > fd_list( n->fds() ); 128 | for ( std::vector< int >::const_iterator it = fd_list.begin(); 129 | it != fd_list.end(); 130 | it++ ) { 131 | sel.add_fd( *it ); 132 | } 133 | 134 | try { 135 | if ( sel.select( n->wait_time() ) < 0 ) { 136 | perror( "select" ); 137 | } 138 | 139 | n->tick(); 140 | 141 | if ( sel.read( STDIN_FILENO ) ) { 142 | char x; 143 | fatal_assert( read( STDIN_FILENO, &x, 1 ) == 1 ); 144 | n->get_current_state().push_back( Parser::UserByte( x ) ); 145 | } 146 | 147 | bool network_ready_to_read = false; 148 | for ( std::vector< int >::const_iterator it = fd_list.begin(); 149 | it != fd_list.end(); 150 | it++ ) { 151 | if ( sel.read( *it ) ) { 152 | /* packet received from the network */ 153 | /* we only read one socket each run */ 154 | network_ready_to_read = true; 155 | } 156 | 157 | if ( sel.error( *it ) ) { 158 | break; 159 | } 160 | } 161 | 162 | if ( network_ready_to_read ) { 163 | n->recv(); 164 | } 165 | } catch ( const std::exception &e ) { 166 | fprintf( stderr, "Client error: %s\n", e.what() ); 167 | } 168 | } 169 | 170 | if ( tcsetattr( STDIN_FILENO, TCSANOW, &saved_termios ) < 0 ) { 171 | perror( "tcsetattr" ); 172 | exit( 1 ); 173 | } 174 | } 175 | 176 | delete n; 177 | } 178 | -------------------------------------------------------------------------------- /src/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | /mosh-client 2 | /mosh-server 3 | -------------------------------------------------------------------------------- /src/frontend/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I../protobufs -I$(srcdir)/../util $(TINFO_CFLAGS) $(protobuf_CFLAGS) $(OPENSSL_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) 3 | AM_LDFLAGS = $(HARDEN_LDFLAGS) 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) $(OPENSSL_LIBS) 5 | 6 | mosh_server_LDADD = $(LDADD) $(LIBUTIL) 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/frontend/stmclient.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 STM_CLIENT_HPP 34 | #define STM_CLIENT_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "completeterminal.h" 41 | #include "networktransport.h" 42 | #include "user.h" 43 | #include "terminaloverlay.h" 44 | 45 | class STMClient { 46 | private: 47 | std::string ip; 48 | std::string port; 49 | std::string key; 50 | int loss_ratio_tolerance; 51 | 52 | int escape_key; 53 | int escape_pass_key; 54 | int escape_pass_key2; 55 | bool escape_requires_lf; 56 | std::wstring escape_key_help; 57 | 58 | struct termios saved_termios, raw_termios; 59 | 60 | struct winsize window_size; 61 | 62 | Terminal::Framebuffer *local_framebuffer, *new_state; 63 | Overlay::OverlayManager overlays; 64 | Network::Transport< Network::UserStream, Terminal::Complete > *network; 65 | Terminal::Display display; 66 | 67 | std::wstring connecting_notification; 68 | bool repaint_requested, lf_entered, quit_sequence_started; 69 | bool clean_shutdown; 70 | 71 | void main_init( void ); 72 | void process_network_input( void ); 73 | bool process_user_input( int fd ); 74 | bool process_resize( void ); 75 | 76 | void output_new_frame( void ); 77 | 78 | bool still_connecting( void ) const 79 | { 80 | /* Initially, network == NULL */ 81 | return network && ( network->get_remote_state_num() == 0 ); 82 | } 83 | 84 | void resume( void ); /* restore state after SIGCONT */ 85 | 86 | public: 87 | STMClient( const char *s_ip, const char *s_port, const char *s_key, const char *predict_mode, 88 | int s_loss_ratio_tolerance ) 89 | : ip( s_ip ), port( s_port ), key( s_key ), loss_ratio_tolerance( s_loss_ratio_tolerance ), 90 | escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ), 91 | escape_requires_lf( false ), escape_key_help( L"?" ), 92 | saved_termios(), raw_termios(), 93 | window_size(), 94 | local_framebuffer( NULL ), 95 | new_state( NULL ), 96 | overlays(), 97 | network( NULL ), 98 | display( true ), /* use TERM environment var to initialize display */ 99 | connecting_notification(), 100 | repaint_requested( false ), 101 | lf_entered( false ), 102 | quit_sequence_started( false ), 103 | clean_shutdown( false ) 104 | { 105 | if ( predict_mode ) { 106 | if ( !strcmp( predict_mode, "always" ) ) { 107 | overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Always ); 108 | } else if ( !strcmp( predict_mode, "never" ) ) { 109 | overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Never ); 110 | } else if ( !strcmp( predict_mode, "adaptive" ) ) { 111 | overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Adaptive ); 112 | } else if ( !strcmp( predict_mode, "experimental" ) ) { 113 | overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Experimental ); 114 | } else { 115 | fprintf( stderr, "Unknown prediction mode %s.\n", predict_mode ); 116 | exit( 1 ); 117 | } 118 | } 119 | } 120 | 121 | void init( void ); 122 | void shutdown( void ); 123 | void main( void ); 124 | 125 | ~STMClient() 126 | { 127 | if ( local_framebuffer != NULL ) { 128 | delete local_framebuffer; 129 | } 130 | 131 | if ( new_state != NULL ) { 132 | delete new_state; 133 | } 134 | 135 | if ( network != NULL ) { 136 | delete network; 137 | } 138 | } 139 | 140 | /* unused */ 141 | STMClient( const STMClient & ); 142 | STMClient & operator=( const STMClient & ); 143 | }; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /src/network/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../crypto -I../protobufs $(protobuf_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) 3 | 4 | noinst_LIBRARIES = libmoshnetwork.a 5 | 6 | libmoshnetwork_a_SOURCES = network.cc network.h networktransport.cc networktransport.h transportfragment.cc transportfragment.h transportsender.cc transportsender.h transportstate.h compressor.cc compressor.h addresses.cc addresses.h 7 | -------------------------------------------------------------------------------- /src/network/addresses.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 "addresses.h" 37 | #include "timestamp.h" 38 | #include "logger.h" 39 | 40 | using namespace Network; 41 | 42 | const unsigned char Addr::v4prefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF}; 43 | 44 | std::vector< Addr > Addresses::get_host_addresses( int *has_change ) 45 | { 46 | struct ifaddrs *ifaddr; 47 | struct ifaddrs *ifa; 48 | std::set< Addr > addr; 49 | int changed = 0; 50 | int rc; 51 | 52 | rc = getifaddrs( &ifaddr ); 53 | if ( rc < 0 ) { 54 | addr = addresses; 55 | goto done; 56 | } 57 | 58 | for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next ) { 59 | if ( !ifa->ifa_addr ) continue; 60 | Addr tmp; 61 | switch ( ifa->ifa_addr->sa_family ) { 62 | case AF_INET: tmp = Addr( *(struct sockaddr_in*) ifa->ifa_addr ); break; 63 | case AF_INET6: tmp = Addr( *(struct sockaddr_in6*) ifa->ifa_addr ); break; 64 | default: continue; 65 | } 66 | log_dbg( LOG_DEBUG_COMMON, "Host address read: %s.\n", tmp.tostring().c_str() ); 67 | addr.insert( tmp ); 68 | } 69 | 70 | freeifaddrs( ifaddr ); 71 | 72 | changed = !( addr == addresses ); 73 | done: 74 | if ( has_change ) { 75 | *has_change = changed; 76 | } 77 | if ( changed ) { 78 | addresses = addr; 79 | } 80 | last_addr_check = frozen_timestamp(); 81 | return std::vector< Addr >( addr.begin(), addr.end() );; 82 | } 83 | 84 | string Addr::tostring( void ) const { 85 | string result; 86 | char dst[INET6_ADDRSTRLEN + 6]; 87 | int family = sa.sa_family; 88 | int port; 89 | const char *tmp; 90 | void *addr; 91 | if (family == AF_INET) { 92 | addr = (void*) &sin.sin_addr; 93 | port = ntohs( sin.sin_port ); 94 | } else if (family == AF_INET6) { 95 | addr = (void*) &sin6.sin6_addr; 96 | port = ntohs( sin6.sin6_port ); 97 | } else if ( family == AF_UNSPEC ) { 98 | return string(""); /* Choice let to the system. */ 99 | } else { 100 | return string(""); 101 | } 102 | tmp = inet_ntop(family, addr, dst, INET6_ADDRSTRLEN); 103 | if ( port ) { 104 | snprintf( dst + strlen(tmp), 6 + 1, ":%d", port ); 105 | } 106 | return string( tmp ); 107 | } 108 | 109 | int Addresses::get_fd( void ) 110 | { 111 | return -1; 112 | } 113 | 114 | bool Addresses::compatible( const Addr &src, const Addr &dst ) { 115 | return src.sa.sa_family == dst.sa.sa_family && 116 | src.is_loopback() == dst.is_loopback() && 117 | dst.is_linklocal() == src.is_linklocal(); 118 | } 119 | -------------------------------------------------------------------------------- /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 "dos_assert.h" 37 | 38 | using namespace Network; 39 | using namespace std; 40 | 41 | string Compressor::compress_str( const string &input ) 42 | { 43 | long unsigned int len = BUFFER_SIZE; 44 | dos_assert( Z_OK == compress( buffer, &len, 45 | reinterpret_cast( input.data() ), 46 | input.size() ) ); 47 | return string( reinterpret_cast( buffer ), len ); 48 | } 49 | 50 | string Compressor::uncompress_str( const string &input ) 51 | { 52 | long unsigned int len = BUFFER_SIZE; 53 | dos_assert( Z_OK == uncompress( buffer, &len, 54 | reinterpret_cast( input.data() ), 55 | input.size() ) ); 56 | return string( reinterpret_cast( buffer ), len ); 57 | } 58 | 59 | /* construct on first use */ 60 | Compressor & Network::get_compressor( void ) 61 | { 62 | static Compressor the_compressor; 63 | return the_compressor; 64 | } 65 | -------------------------------------------------------------------------------- /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 | private: 41 | static const int BUFFER_SIZE = 2048 * 2048; /* effective limit on terminal size */ 42 | 43 | unsigned char *buffer; 44 | 45 | public: 46 | Compressor() : buffer( NULL ) { buffer = new unsigned char[ BUFFER_SIZE ]; } 47 | ~Compressor() { if ( buffer ) { delete[] buffer; } } 48 | 49 | std::string compress_str( const std::string &input ); 50 | std::string uncompress_str( const std::string &input ); 51 | 52 | /* unused */ 53 | Compressor( const Compressor & ); 54 | Compressor & operator=( const Compressor & ); 55 | }; 56 | 57 | Compressor & get_compressor( void ); 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/network/networktransport.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 NETWORK_TRANSPORT_HPP 34 | #define NETWORK_TRANSPORT_HPP 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "network.h" 43 | #include "transportsender.h" 44 | #include "transportfragment.h" 45 | 46 | 47 | namespace Network { 48 | template 49 | class Transport 50 | { 51 | private: 52 | /* the underlying, encrypted network connection */ 53 | Connection connection; 54 | 55 | /* sender side */ 56 | TransportSender sender; 57 | 58 | /* helper methods for recv() */ 59 | void process_throwaway_until( uint64_t throwaway_num ); 60 | 61 | /* simple receiver */ 62 | list< TimestampedState > received_states; 63 | uint64_t receiver_quench_timer; 64 | RemoteState last_receiver_state; /* the state we were in when user last queried state */ 65 | FragmentAssembly fragments; 66 | bool verbose; 67 | 68 | public: 69 | Transport( MyState &initial_state, RemoteState &initial_remote, 70 | const char *desired_ip, const char *desired_port, 71 | int loss_ratio_tolerance ); 72 | Transport( MyState &initial_state, RemoteState &initial_remote, 73 | const char *key_str, const char *ip, const char *port, 74 | int loss_ratio_tolerance ); 75 | 76 | /* Send data or an ack if necessary. */ 77 | void tick( void ) { sender.tick(); } 78 | 79 | /* Returns the number of ms to wait until next possible event. */ 80 | int wait_time( void ) { return sender.wait_time(); } 81 | 82 | /* Blocks waiting for a packet. */ 83 | void recv( void ); 84 | 85 | /* Find diff between last receiver state and current remote state, then rationalize states. */ 86 | string get_remote_diff( void ); 87 | 88 | /* Shut down other side of connection. */ 89 | /* Illegal to change current_state after this. */ 90 | void start_shutdown( void ) { sender.start_shutdown(); } 91 | bool shutdown_in_progress( void ) const { return sender.get_shutdown_in_progress(); } 92 | bool shutdown_acknowledged( void ) const { return sender.get_shutdown_acknowledged(); } 93 | bool shutdown_ack_timed_out( void ) const { return sender.shutdown_ack_timed_out(); } 94 | bool has_remote_addr( void ) const { return connection.get_has_remote_addr(); } 95 | 96 | /* Other side has requested shutdown and we have sent one ACK */ 97 | bool counterparty_shutdown_ack_sent( void ) const { return sender.get_counterparty_shutdown_acknowledged(); } 98 | 99 | std::string port( void ) const { return connection.port(); } 100 | string get_key( void ) const { return connection.get_key(); } 101 | 102 | MyState &get_current_state( void ) { return sender.get_current_state(); } 103 | void set_current_state( const MyState &x ) { sender.set_current_state( x ); } 104 | 105 | uint64_t get_remote_state_num( void ) const { return received_states.back().num; } 106 | 107 | const TimestampedState & get_latest_remote_state( void ) const { return received_states.back(); } 108 | 109 | const std::vector< int > fds( void ) const { return connection.fds(); } 110 | 111 | void set_verbose( void ) { sender.set_verbose(); verbose = true; } 112 | 113 | void set_send_delay( int new_delay ) { sender.set_send_delay( new_delay ); } 114 | 115 | uint64_t get_sent_state_acked_timestamp( void ) const { return sender.get_sent_state_acked_timestamp(); } 116 | uint64_t get_sent_state_acked( void ) const { return sender.get_sent_state_acked(); } 117 | uint64_t get_sent_state_last( void ) const { return sender.get_sent_state_last(); } 118 | 119 | unsigned int send_interval( void ) const { return sender.send_interval(); } 120 | 121 | const Addr &get_remote_addr( void ) const { return connection.get_remote_addr(); } 122 | socklen_t get_remote_addr_len( void ) const { return connection.get_remote_addr_len(); } 123 | 124 | const NetworkException *get_send_exception( void ) const { return connection.get_send_exception(); } 125 | }; 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /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 "transportinstruction.pb.h" 41 | 42 | using std::vector; 43 | using std::string; 44 | using namespace TransportBuffers; 45 | 46 | namespace Network { 47 | static const int HEADER_LEN = 66; 48 | 49 | class Fragment 50 | { 51 | private: 52 | static const size_t frag_header_len = sizeof( uint64_t ) + sizeof( uint16_t ); 53 | 54 | public: 55 | uint64_t id; 56 | uint16_t fragment_num; 57 | bool final; 58 | 59 | bool initialized; 60 | 61 | string contents; 62 | 63 | Fragment() 64 | : id( -1 ), fragment_num( -1 ), final( false ), initialized( false ), contents() 65 | {} 66 | 67 | Fragment( uint64_t s_id, uint16_t s_fragment_num, bool s_final, string s_contents ) 68 | : id( s_id ), fragment_num( s_fragment_num ), final( s_final ), initialized( true ), 69 | contents( s_contents ) 70 | {} 71 | 72 | Fragment( string &x ); 73 | 74 | string tostring( void ); 75 | 76 | bool operator==( const Fragment &x ) const; 77 | }; 78 | 79 | class FragmentAssembly 80 | { 81 | private: 82 | vector fragments; 83 | uint64_t current_id; 84 | int fragments_arrived, fragments_total; 85 | 86 | public: 87 | FragmentAssembly() : fragments(), current_id( -1 ), fragments_arrived( 0 ), fragments_total( -1 ) {} 88 | bool add_fragment( Fragment &inst ); 89 | Instruction get_assembly( void ); 90 | }; 91 | 92 | class Fragmenter 93 | { 94 | private: 95 | uint64_t next_instruction_id; 96 | Instruction last_instruction; 97 | int last_MTU; 98 | 99 | public: 100 | Fragmenter() : next_instruction_id( 0 ), last_instruction(), last_MTU( -1 ) 101 | { 102 | last_instruction.set_old_num( -1 ); 103 | last_instruction.set_new_num( -1 ); 104 | } 105 | vector make_fragments( const Instruction &inst, int MTU ); 106 | uint64_t last_ack_sent( void ) const { return last_instruction.ack_num(); } 107 | }; 108 | 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /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, State &s_state ) 46 | : timestamp( s_timestamp ), num( s_num ), state( s_state ) 47 | {} 48 | 49 | /* For use with find_if, remove_if */ 50 | bool num_eq( uint64_t v ) const { return num == v; } 51 | bool num_lt( uint64_t v ) const { return num < v; } 52 | }; 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /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) 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 | option optimize_for = LITE_RUNTIME; 2 | 3 | package HostBuffers; 4 | 5 | message HostMessage { 6 | repeated Instruction instruction = 1; 7 | } 8 | 9 | message Instruction { 10 | extensions 2 to max; 11 | } 12 | 13 | message HostBytes { 14 | optional bytes hoststring = 4; 15 | } 16 | 17 | message ResizeMessage { 18 | optional int32 width = 5; 19 | optional int32 height = 6; 20 | } 21 | 22 | message EchoAck { 23 | optional uint64 echo_ack_num = 8; 24 | } 25 | 26 | extend Instruction { 27 | optional HostBytes hostbytes = 2; 28 | optional ResizeMessage resize = 3; 29 | optional EchoAck echoack = 7; 30 | } 31 | -------------------------------------------------------------------------------- /src/protobufs/transportinstruction.proto: -------------------------------------------------------------------------------- 1 | option optimize_for = LITE_RUNTIME; 2 | 3 | package TransportBuffers; 4 | 5 | message Instruction { 6 | optional uint32 protocol_version = 1; 7 | 8 | optional uint64 old_num = 2; 9 | optional uint64 new_num = 3; 10 | optional uint64 ack_num = 4; 11 | optional uint64 throwaway_num = 5; 12 | 13 | optional bytes diff = 6; 14 | 15 | optional bytes chaff = 7; 16 | } 17 | -------------------------------------------------------------------------------- /src/protobufs/userinput.proto: -------------------------------------------------------------------------------- 1 | option optimize_for = LITE_RUNTIME; 2 | 3 | package ClientBuffers; 4 | 5 | message UserMessage { 6 | repeated Instruction instruction = 1; 7 | } 8 | 9 | message Instruction { 10 | extensions 2 to max; 11 | } 12 | 13 | message Keystroke { 14 | optional bytes keys = 4; 15 | } 16 | 17 | message ResizeMessage { 18 | optional int32 width = 5; 19 | optional int32 height = 6; 20 | } 21 | 22 | extend Instruction { 23 | optional Keystroke keystroke = 2; 24 | optional ResizeMessage resize = 3; 25 | } 26 | -------------------------------------------------------------------------------- /src/statesync/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../terminal -I../protobufs $(protobuf_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_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 "parser.h" 40 | #include "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 | private: 47 | Parser::UTF8Parser parser; 48 | Terminal::Emulator terminal; 49 | Terminal::Display display; 50 | 51 | typedef std::list< std::pair > input_history_type; 52 | input_history_type input_history; 53 | uint64_t echo_ack; 54 | 55 | static const int ECHO_TIMEOUT = 50; /* for late ack */ 56 | 57 | public: 58 | Complete( size_t width, size_t height ) : parser(), terminal( width, height ), display( false ), 59 | input_history(), echo_ack( 0 ) {} 60 | 61 | std::string act( const std::string &str ); 62 | std::string act( const Parser::Action *act ); 63 | 64 | const Framebuffer & get_fb( void ) const { return terminal.get_fb(); } 65 | bool parser_grounded( void ) const { return parser.is_grounded(); } 66 | 67 | uint64_t get_echo_ack( void ) const { return echo_ack; } 68 | bool set_echo_ack( uint64_t now ); 69 | void register_input_frame( uint64_t n, uint64_t now ); 70 | int wait_time( uint64_t now ) const; 71 | 72 | /* interface for Network::Transport */ 73 | void subtract( const Complete * ) const {} 74 | std::string diff_from( const Complete &existing ) const; 75 | void apply_string( std::string diff ); 76 | bool operator==( const Complete &x ) const; 77 | 78 | bool compare( const Complete &other ) const; 79 | }; 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/statesync/user.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 "user.h" 37 | #include "fatal_assert.h" 38 | #include "userinput.pb.h" 39 | 40 | using namespace Parser; 41 | using namespace Network; 42 | using namespace ClientBuffers; 43 | 44 | void UserStream::subtract( const UserStream *prefix ) 45 | { 46 | // if we are subtracting ourself from ourself, just clear the deque 47 | if ( this == prefix ) { 48 | actions.clear(); 49 | return; 50 | } 51 | for ( deque::const_iterator i = prefix->actions.begin(); 52 | i != prefix->actions.end(); 53 | i++ ) { 54 | assert( this != prefix ); 55 | assert( !actions.empty() ); 56 | assert( *i == actions.front() ); 57 | actions.pop_front(); 58 | } 59 | } 60 | 61 | string UserStream::diff_from( const UserStream &existing ) const 62 | { 63 | deque::const_iterator my_it = actions.begin(); 64 | 65 | for ( deque::const_iterator i = existing.actions.begin(); 66 | i != existing.actions.end(); 67 | i++ ) { 68 | assert( my_it != actions.end() ); 69 | assert( *i == *my_it ); 70 | my_it++; 71 | } 72 | 73 | ClientBuffers::UserMessage output; 74 | 75 | while ( my_it != actions.end() ) { 76 | switch ( my_it->type ) { 77 | case UserByteType: 78 | { 79 | char the_byte = my_it->userbyte.c; 80 | /* can we combine this with a previous Keystroke? */ 81 | if ( (output.instruction_size() > 0) 82 | && (output.instruction( output.instruction_size() - 1 ).HasExtension( keystroke )) ) { 83 | output.mutable_instruction( output.instruction_size() - 1 )->MutableExtension( keystroke )->mutable_keys()->append( string( &the_byte, 1 ) ); 84 | } else { 85 | Instruction *new_inst = output.add_instruction(); 86 | new_inst->MutableExtension( keystroke )->set_keys( &the_byte, 1 ); 87 | } 88 | } 89 | break; 90 | case ResizeType: 91 | { 92 | Instruction *new_inst = output.add_instruction(); 93 | new_inst->MutableExtension( resize )->set_width( my_it->resize.width ); 94 | new_inst->MutableExtension( resize )->set_height( my_it->resize.height ); 95 | } 96 | break; 97 | default: 98 | assert( false ); 99 | break; 100 | } 101 | 102 | my_it++; 103 | } 104 | 105 | return output.SerializeAsString(); 106 | } 107 | 108 | void UserStream::apply_string( string diff ) 109 | { 110 | ClientBuffers::UserMessage input; 111 | fatal_assert( input.ParseFromString( diff ) ); 112 | 113 | for ( int i = 0; i < input.instruction_size(); i++ ) { 114 | if ( input.instruction( i ).HasExtension( keystroke ) ) { 115 | string the_bytes = input.instruction( i ).GetExtension( keystroke ).keys(); 116 | for ( unsigned int loc = 0; loc < the_bytes.size(); loc++ ) { 117 | actions.push_back( UserEvent( UserByte( the_bytes.at( loc ) ) ) ); 118 | } 119 | } else if ( input.instruction( i ).HasExtension( resize ) ) { 120 | actions.push_back( UserEvent( Resize( input.instruction( i ).GetExtension( resize ).width(), 121 | input.instruction( i ).GetExtension( resize ).height() ) ) ); 122 | } 123 | } 124 | } 125 | 126 | const Parser::Action *UserStream::get_action( unsigned int i ) const 127 | { 128 | switch( actions[ i ].type ) { 129 | case UserByteType: 130 | return &( actions[ i ].userbyte ); 131 | case ResizeType: 132 | return &( actions[ i ].resize ); 133 | default: 134 | assert( false ); 135 | return NULL; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /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 "parseraction.h" 42 | 43 | using std::deque; 44 | using std::list; 45 | using std::string; 46 | 47 | namespace Network { 48 | enum UserEventType { 49 | UserByteType = 0, 50 | ResizeType = 1 51 | }; 52 | 53 | class UserEvent 54 | { 55 | public: 56 | UserEventType type; 57 | Parser::UserByte userbyte; 58 | Parser::Resize resize; 59 | 60 | UserEvent( Parser::UserByte s_userbyte ) : type( UserByteType ), userbyte( s_userbyte ), resize( -1, -1 ) {} 61 | UserEvent( Parser::Resize s_resize ) : type( ResizeType ), userbyte( 0 ), resize( s_resize ) {} 62 | 63 | UserEvent() /* default constructor required by C++11 STL */ 64 | : type( UserByteType ), 65 | userbyte( 0 ), 66 | resize( -1, -1 ) 67 | { 68 | assert( false ); 69 | } 70 | 71 | bool operator==( const UserEvent &x ) const { return ( type == x.type ) && ( userbyte == x.userbyte ) && ( resize == x.resize ); } 72 | }; 73 | 74 | class UserStream 75 | { 76 | private: 77 | deque actions; 78 | 79 | public: 80 | UserStream() : actions() {} 81 | 82 | void push_back( Parser::UserByte s_userbyte ) { actions.push_back( UserEvent( s_userbyte ) ); } 83 | void push_back( Parser::Resize s_resize ) { actions.push_back( UserEvent( s_resize ) ); } 84 | 85 | bool empty( void ) const { return actions.empty(); } 86 | size_t size( void ) const { return actions.size(); } 87 | const Parser::Action *get_action( unsigned int i ) const; 88 | 89 | /* interface for Network::Transport */ 90 | void subtract( const UserStream *prefix ); 91 | string diff_from( const UserStream &existing ) const; 92 | void apply_string( string diff ); 93 | bool operator==( const UserStream &x ) const { return actions == x.actions; } 94 | 95 | bool compare( const UserStream & ) { return false; } 96 | }; 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/terminal/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(srcdir)/../util $(TINFO_CFLAGS) 2 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_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.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 | #include 37 | #include 38 | 39 | #include "parser.h" 40 | 41 | const Parser::StateFamily Parser::family; 42 | 43 | static void append_or_delete( Parser::Action *act, 44 | std::list &vec ) 45 | { 46 | assert( act ); 47 | 48 | if ( typeid( *act ) != typeid( Parser::Ignore ) ) { 49 | vec.push_back( act ); 50 | } else { 51 | delete act; 52 | } 53 | } 54 | 55 | std::list Parser::Parser::input( wchar_t ch ) 56 | { 57 | std::list ret; 58 | 59 | Transition tx = state->input( ch ); 60 | 61 | if ( tx.next_state != NULL ) { 62 | append_or_delete( state->exit(), ret ); 63 | } 64 | 65 | append_or_delete( tx.action, ret ); 66 | tx.action = NULL; 67 | 68 | if ( tx.next_state != NULL ) { 69 | append_or_delete( tx.next_state->enter(), ret ); 70 | state = tx.next_state; 71 | } 72 | 73 | return ret; 74 | } 75 | 76 | Parser::UTF8Parser::UTF8Parser() 77 | : parser(), buf_len( 0 ) 78 | { 79 | assert( BUF_SIZE >= (size_t)MB_CUR_MAX ); 80 | buf[0] = '\0'; 81 | } 82 | 83 | std::list Parser::UTF8Parser::input( char c ) 84 | { 85 | assert( buf_len < BUF_SIZE ); 86 | 87 | buf[ buf_len++ ] = c; 88 | 89 | /* This function will only work in a UTF-8 locale. */ 90 | 91 | wchar_t pwc; 92 | mbstate_t ps; 93 | memset( &ps, 0, sizeof( ps ) ); 94 | 95 | size_t total_bytes_parsed = 0; 96 | size_t orig_buf_len = buf_len; 97 | std::list ret; 98 | 99 | /* this routine is somewhat complicated in order to comply with 100 | Unicode 6.0, section 3.9, "Best Practices for using U+FFFD" */ 101 | 102 | while ( total_bytes_parsed != orig_buf_len ) { 103 | assert( total_bytes_parsed < orig_buf_len ); 104 | assert( buf_len > 0 ); 105 | size_t bytes_parsed = mbrtowc( &pwc, buf, buf_len, &ps ); 106 | 107 | /* this returns 0 when n = 0! */ 108 | 109 | if ( bytes_parsed == 0 ) { 110 | /* character was NUL, accept and clear buffer */ 111 | assert( buf_len == 1 ); 112 | buf_len = 0; 113 | pwc = L'\0'; 114 | bytes_parsed = 1; 115 | } else if ( bytes_parsed == (size_t) -1 ) { 116 | /* invalid sequence, use replacement character and try again with last char */ 117 | assert( errno == EILSEQ ); 118 | if ( buf_len > 1 ) { 119 | buf[ 0 ] = buf[ buf_len - 1 ]; 120 | bytes_parsed = buf_len - 1; 121 | buf_len = 1; 122 | } else { 123 | buf_len = 0; 124 | bytes_parsed = 1; 125 | } 126 | pwc = (wchar_t) 0xFFFD; 127 | } else if ( bytes_parsed == (size_t) -2 ) { 128 | /* can't parse incomplete multibyte character */ 129 | total_bytes_parsed += buf_len; 130 | continue; 131 | } else { 132 | /* parsed into pwc, accept */ 133 | assert( bytes_parsed <= buf_len ); 134 | memmove( buf, buf + bytes_parsed, buf_len - bytes_parsed ); 135 | buf_len = buf_len - bytes_parsed; 136 | } 137 | 138 | /* Cast to unsigned for checks, because some 139 | platforms (e.g. ARM) use uint32_t as wchar_t, 140 | causing compiler warning on "pwc > 0" check. */ 141 | uint64_t pwcheck = pwc; 142 | 143 | if ( pwcheck > 0x10FFFF ) { /* outside Unicode range */ 144 | pwc = (wchar_t) 0xFFFD; 145 | } 146 | 147 | if ( (pwcheck >= 0xD800) && (pwcheck <= 0xDFFF) ) { /* surrogate code point */ 148 | /* 149 | OS X unfortunately allows these sequences without EILSEQ, but 150 | they are ill-formed UTF-8 and we shouldn't repeat them to the 151 | user's terminal. 152 | */ 153 | pwc = (wchar_t) 0xFFFD; 154 | } 155 | 156 | std::list vec = parser.input( pwc ); 157 | ret.insert( ret.end(), vec.begin(), vec.end() ); 158 | 159 | total_bytes_parsed += bytes_parsed; 160 | } 161 | 162 | return ret; 163 | } 164 | 165 | Parser::Parser::Parser( const Parser &other ) 166 | : state( other.state ) 167 | {} 168 | 169 | Parser::Parser & Parser::Parser::operator=( const Parser &other ) 170 | { 171 | state = other.state; 172 | return *this; 173 | } 174 | -------------------------------------------------------------------------------- /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 | #include 42 | 43 | #include "parsertransition.h" 44 | #include "parseraction.h" 45 | #include "parserstate.h" 46 | #include "parserstatefamily.h" 47 | 48 | namespace Parser { 49 | extern const StateFamily family; 50 | 51 | class Parser { 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 | std::list input( wchar_t ch ); 63 | 64 | bool operator==( const Parser &x ) const 65 | { 66 | return state == x.state; 67 | } 68 | 69 | bool is_grounded( void ) const { return state == &family.s_Ground; } 70 | }; 71 | 72 | static const size_t BUF_SIZE = 8; 73 | 74 | class UTF8Parser { 75 | private: 76 | Parser parser; 77 | 78 | char buf[ BUF_SIZE ]; 79 | size_t buf_len; 80 | 81 | public: 82 | UTF8Parser(); 83 | 84 | std::list input( char c ); 85 | 86 | bool operator==( const UTF8Parser &x ) const 87 | { 88 | return parser == x.parser; 89 | } 90 | 91 | bool is_grounded( void ) const { return parser.is_grounded(); } 92 | }; 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /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 "parseraction.h" 37 | #include "terminal.h" 38 | 39 | using namespace Parser; 40 | 41 | std::string Action::str( void ) 42 | { 43 | char thechar[ 10 ] = { 0 }; 44 | if ( char_present ) { 45 | if ( iswprint( ch ) ) 46 | snprintf( thechar, 10, "(%lc)", (wint_t)ch ); 47 | else 48 | snprintf( thechar, 10, "(0x%x)", (unsigned int)ch ); 49 | } 50 | 51 | return name() + std::string( thechar ); 52 | } 53 | 54 | void Print::act_on_terminal( Terminal::Emulator *emu ) const 55 | { 56 | emu->print( this ); 57 | } 58 | 59 | void Execute::act_on_terminal( Terminal::Emulator *emu ) const 60 | { 61 | emu->execute( this ); 62 | } 63 | 64 | void Clear::act_on_terminal( Terminal::Emulator *emu ) const 65 | { 66 | emu->dispatch.clear( this ); 67 | } 68 | 69 | void Param::act_on_terminal( Terminal::Emulator *emu ) const 70 | { 71 | emu->dispatch.newparamchar( this ); 72 | } 73 | 74 | void Collect::act_on_terminal( Terminal::Emulator *emu ) const 75 | { 76 | emu->dispatch.collect( this ); 77 | } 78 | 79 | void CSI_Dispatch::act_on_terminal( Terminal::Emulator *emu ) const 80 | { 81 | emu->CSI_dispatch( this ); 82 | } 83 | 84 | void Esc_Dispatch::act_on_terminal( Terminal::Emulator *emu ) const 85 | { 86 | emu->Esc_dispatch( this ); 87 | } 88 | 89 | void OSC_Put::act_on_terminal( Terminal::Emulator *emu ) const 90 | { 91 | emu->dispatch.OSC_put( this ); 92 | } 93 | 94 | void OSC_Start::act_on_terminal( Terminal::Emulator *emu ) const 95 | { 96 | emu->dispatch.OSC_start( this ); 97 | } 98 | 99 | void OSC_End::act_on_terminal( Terminal::Emulator *emu ) const 100 | { 101 | emu->OSC_end( this ); 102 | } 103 | 104 | void UserByte::act_on_terminal( Terminal::Emulator *emu ) const 105 | { 106 | emu->dispatch.terminal_to_host.append( emu->user.input( this, 107 | emu->fb.ds.application_mode_cursor_keys ) ); 108 | } 109 | 110 | void Resize::act_on_terminal( Terminal::Emulator *emu ) const 111 | { 112 | emu->resize( width, height ); 113 | handled = true; 114 | } 115 | 116 | bool Action::operator==( const Action &other ) const 117 | { 118 | return ( char_present == other.char_present ) 119 | && ( ch == other.ch ) 120 | && ( handled == other.handled ); 121 | } 122 | -------------------------------------------------------------------------------- /src/terminal/parseraction.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 PARSERACTION_HPP 34 | #define PARSERACTION_HPP 35 | 36 | #include 37 | 38 | namespace Terminal { 39 | class Emulator; 40 | } 41 | 42 | namespace Parser { 43 | class Action 44 | { 45 | public: 46 | bool char_present; 47 | wchar_t ch; 48 | mutable bool handled; 49 | 50 | std::string str( void ); 51 | 52 | virtual std::string name( void ) = 0; 53 | 54 | virtual void act_on_terminal( Terminal::Emulator * ) const {}; 55 | 56 | Action() : char_present( false ), ch( -1 ), handled( false ) {}; 57 | virtual ~Action() {}; 58 | 59 | virtual bool operator==( const Action &other ) const; 60 | }; 61 | 62 | class Ignore : public Action { 63 | public: std::string name( void ) { return std::string( "Ignore" ); } 64 | }; 65 | class Print : public Action { 66 | public: 67 | std::string name( void ) { return std::string( "Print" ); } 68 | void act_on_terminal( Terminal::Emulator *emu ) const; 69 | }; 70 | class Execute : public Action { 71 | public: 72 | std::string name( void ) { return std::string( "Execute" ); } 73 | void act_on_terminal( Terminal::Emulator *emu ) const; 74 | }; 75 | class Clear : public Action { 76 | public: 77 | std::string name( void ) { return std::string( "Clear" ); } 78 | void act_on_terminal( Terminal::Emulator *emu ) const; 79 | }; 80 | class Collect : public Action { 81 | public: 82 | std::string name( void ) { return std::string( "Collect" ); } 83 | void act_on_terminal( Terminal::Emulator *emu ) const; 84 | }; 85 | class Param : public Action { 86 | public: 87 | std::string name( void ) { return std::string( "Param" ); } 88 | void act_on_terminal( Terminal::Emulator *emu ) const; 89 | }; 90 | class Esc_Dispatch : public Action { 91 | public: 92 | std::string name( void ) { return std::string( "Esc_Dispatch" ); } 93 | void act_on_terminal( Terminal::Emulator *emu ) const; 94 | }; 95 | class CSI_Dispatch : public Action { 96 | public: 97 | std::string name( void ) { return std::string( "CSI_Dispatch" ); } 98 | void act_on_terminal( Terminal::Emulator *emu ) const; 99 | }; 100 | class Hook : public Action { 101 | public: std::string name( void ) { return std::string( "Hook" ); } 102 | }; 103 | class Put : public Action { 104 | public: std::string name( void ) { return std::string( "Put" ); } 105 | }; 106 | class Unhook : public Action { 107 | public: std::string name( void ) { return std::string( "Unhook" ); } 108 | }; 109 | class OSC_Start : public Action { 110 | public: 111 | std::string name( void ) { return std::string( "OSC_Start" ); } 112 | void act_on_terminal( Terminal::Emulator *emu ) const; 113 | }; 114 | class OSC_Put : public Action { 115 | public: 116 | std::string name( void ) { return std::string( "OSC_Put" ); } 117 | void act_on_terminal( Terminal::Emulator *emu ) const; 118 | }; 119 | class OSC_End : public Action { 120 | public: 121 | std::string name( void ) { return std::string( "OSC_End" ); } 122 | void act_on_terminal( Terminal::Emulator *emu ) const; 123 | }; 124 | 125 | class UserByte : public Action { 126 | /* user keystroke -- not part of the host-source state machine*/ 127 | public: 128 | char c; /* The user-source byte. We don't try to interpret the charset */ 129 | 130 | std::string name( void ) { return std::string( "UserByte" ); } 131 | void act_on_terminal( Terminal::Emulator *emu ) const; 132 | 133 | UserByte( int s_c ) : c( s_c ) {} 134 | 135 | bool operator==( const UserByte &other ) const 136 | { 137 | return c == other.c; 138 | } 139 | }; 140 | 141 | class Resize : public Action { 142 | /* resize event -- not part of the host-source state machine*/ 143 | public: 144 | size_t width, height; 145 | 146 | std::string name( void ) { return std::string( "Resize" ); } 147 | void act_on_terminal( Terminal::Emulator *emu ) const; 148 | 149 | Resize( size_t s_width, size_t s_height ) 150 | : width( s_width ), 151 | height( s_height ) 152 | {} 153 | 154 | bool operator==( const Resize &other ) const 155 | { 156 | return ( width == other.width ) && ( height == other.height ); 157 | } 158 | }; 159 | } 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /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 Action *enter( void ) const { return new Ignore; } 54 | virtual Action *exit( void ) const { return new Ignore; } 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 | Transition input_state_rule( wchar_t ch ) const; 65 | }; 66 | 67 | class Escape : public State { 68 | Action *enter( void ) const; 69 | Transition input_state_rule( wchar_t ch ) const; 70 | }; 71 | 72 | class Escape_Intermediate : public State { 73 | Transition input_state_rule( wchar_t ch ) const; 74 | }; 75 | 76 | class CSI_Entry : public State { 77 | Action *enter( void ) const; 78 | Transition input_state_rule( wchar_t ch ) const; 79 | }; 80 | class CSI_Param : public State { 81 | Transition input_state_rule( wchar_t ch ) const; 82 | }; 83 | class CSI_Intermediate : public State { 84 | Transition input_state_rule( wchar_t ch ) const; 85 | }; 86 | class CSI_Ignore : public State { 87 | Transition input_state_rule( wchar_t ch ) const; 88 | }; 89 | 90 | class DCS_Entry : public State { 91 | Action *enter( void ) const; 92 | Transition input_state_rule( wchar_t ch ) const; 93 | }; 94 | class DCS_Param : public State { 95 | Transition input_state_rule( wchar_t ch ) const; 96 | }; 97 | class DCS_Intermediate : public State { 98 | Transition input_state_rule( wchar_t ch ) const; 99 | }; 100 | class DCS_Passthrough : public State { 101 | Action *enter( void ) const; 102 | Transition input_state_rule( wchar_t ch ) const; 103 | Action *exit( void ) const; 104 | }; 105 | class DCS_Ignore : public State { 106 | Transition input_state_rule( wchar_t ch ) const; 107 | }; 108 | 109 | class OSC_String : public State { 110 | Action *enter( void ) const; 111 | Transition input_state_rule( wchar_t ch ) const; 112 | Action *exit( void ) const; 113 | }; 114 | class SOS_PM_APC_String : public State { 115 | Transition input_state_rule( wchar_t ch ) const; 116 | }; 117 | } 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /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(), 63 | s_CSI_Entry(), s_CSI_Param(), s_CSI_Intermediate(), s_CSI_Ignore(), 64 | s_DCS_Entry(), s_DCS_Param(), s_DCS_Intermediate(), 65 | s_DCS_Passthrough(), s_DCS_Ignore(), 66 | s_OSC_String(), s_SOS_PM_APC_String() 67 | { 68 | s_Ground.setfamily( this ); 69 | s_Escape.setfamily( this ); 70 | s_Escape_Intermediate.setfamily( this ); 71 | s_CSI_Entry.setfamily( this ); 72 | s_CSI_Param.setfamily( this ); 73 | s_CSI_Intermediate.setfamily( this ); 74 | s_CSI_Ignore.setfamily( this ); 75 | s_DCS_Entry.setfamily( this ); 76 | s_DCS_Param.setfamily( this ); 77 | s_DCS_Intermediate.setfamily( this ); 78 | s_DCS_Passthrough.setfamily( this ); 79 | s_DCS_Ignore.setfamily( this ); 80 | s_OSC_String.setfamily( this ); 81 | s_SOS_PM_APC_String.setfamily( this ); 82 | } 83 | }; 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /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 "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 | Action *action; 49 | State *next_state; 50 | 51 | Transition( const Transition &x ) 52 | : action( x.action ), 53 | next_state( x.next_state ) {} 54 | Transition & operator=( const Transition &t ) 55 | { 56 | action = t.action; 57 | next_state = t.next_state; 58 | 59 | return *this; 60 | } 61 | virtual ~Transition() 62 | { 63 | // Indicate to checkers that we don't own *action anymore 64 | action = NULL; 65 | } 66 | 67 | Transition( Action *s_action=new Ignore, State *s_next_state=NULL ) 68 | : action( s_action ), next_state( s_next_state ) 69 | {} 70 | 71 | // This is only ever used in the 1-argument form; 72 | // we use this instead of an initializer to 73 | // tell Coverity the object never owns *action. 74 | Transition( State *s_next_state, Action *s_action=new Ignore ) 75 | : action( s_action ), next_state( s_next_state ) 76 | {} 77 | }; 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /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 "parseraction.h" 42 | #include "terminalframebuffer.h" 43 | #include "terminaldispatcher.h" 44 | #include "terminaluserinput.h" 45 | #include "terminaldisplay.h" 46 | 47 | namespace Terminal { 48 | class Emulator { 49 | friend void Parser::Print::act_on_terminal( Emulator * ) const; 50 | friend void Parser::Execute::act_on_terminal( Emulator * ) const; 51 | friend void Parser::Clear::act_on_terminal( Emulator * ) const; 52 | friend void Parser::Param::act_on_terminal( Emulator * ) const; 53 | friend void Parser::Collect::act_on_terminal( Emulator * ) const; 54 | friend void Parser::CSI_Dispatch::act_on_terminal( Emulator * ) const; 55 | friend void Parser::Esc_Dispatch::act_on_terminal( Emulator * ) const; 56 | friend void Parser::OSC_Start::act_on_terminal( Emulator * ) const; 57 | friend void Parser::OSC_Put::act_on_terminal( Emulator * ) const; 58 | friend void Parser::OSC_End::act_on_terminal( Emulator * ) const; 59 | 60 | friend void Parser::UserByte::act_on_terminal( Emulator * ) const; 61 | friend void Parser::Resize::act_on_terminal( Emulator * ) const; 62 | 63 | private: 64 | Framebuffer fb; 65 | Dispatcher dispatch; 66 | UserInput user; 67 | 68 | /* action methods */ 69 | void print( const Parser::Print *act ); 70 | void execute( const Parser::Execute *act ); 71 | void CSI_dispatch( const Parser::CSI_Dispatch *act ); 72 | void Esc_dispatch( const Parser::Esc_Dispatch *act ); 73 | void OSC_end( const Parser::OSC_End *act ); 74 | void resize( size_t s_width, size_t s_height ); 75 | 76 | public: 77 | Emulator( size_t s_width, size_t s_height ); 78 | 79 | std::string read_octets_to_host( void ); 80 | 81 | const Framebuffer & get_fb( void ) const { return fb; } 82 | 83 | bool operator==( Emulator const &x ) const; 84 | }; 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /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 { ESCAPE, CSI, CONTROL }; 58 | 59 | class Function { 60 | public: 61 | Function() : function( NULL ), clears_wrap_state( true ) {} 62 | Function( Function_Type type, std::string dispatch_chars, 63 | void (*s_function)( Framebuffer *, Dispatcher * ), 64 | bool s_clears_wrap_state = true ); 65 | void (*function)( Framebuffer *, Dispatcher * ); 66 | bool clears_wrap_state; 67 | }; 68 | 69 | typedef std::map dispatch_map_t; 70 | 71 | class DispatchRegistry { 72 | public: 73 | dispatch_map_t escape; 74 | dispatch_map_t CSI; 75 | dispatch_map_t control; 76 | 77 | DispatchRegistry() : escape(), CSI(), control() {} 78 | }; 79 | 80 | DispatchRegistry & get_global_dispatch_registry( void ); 81 | 82 | class Dispatcher { 83 | private: 84 | std::string params; 85 | std::vector parsed_params; 86 | bool parsed; 87 | 88 | std::string dispatch_chars; 89 | std::vector OSC_string; /* only used to set the window title */ 90 | 91 | void parse_params( void ); 92 | 93 | public: 94 | static const int PARAM_MAX = 65535; 95 | /* prevent evil escape sequences from causing long loops */ 96 | 97 | std::string terminal_to_host; /* this is the reply string */ 98 | 99 | Dispatcher(); 100 | int getparam( size_t N, int defaultval ); 101 | int param_count( void ); 102 | 103 | void newparamchar( const Parser::Param *act ); 104 | void collect( const Parser::Collect *act ); 105 | void clear( const Parser::Clear *act ); 106 | 107 | std::string str( void ); 108 | 109 | void dispatch( Function_Type type, const Parser::Action *act, Framebuffer *fb ); 110 | std::string get_dispatch_chars( void ) const { return dispatch_chars; } 111 | std::vector get_OSC_string( void ) const { return OSC_string; } 112 | 113 | void OSC_put( const Parser::OSC_Put *act ); 114 | void OSC_start( const Parser::OSC_Start *act ); 115 | void OSC_dispatch( const Parser::OSC_End *act, Framebuffer *fb ); 116 | 117 | bool operator==( const Dispatcher &x ) const; 118 | }; 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /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 "terminalframebuffer.h" 37 | 38 | namespace Terminal { 39 | /* variables used within a new_frame */ 40 | class FrameState { 41 | public: 42 | int x, y; 43 | bool force_next_put; 44 | std::string str; 45 | 46 | int cursor_x, cursor_y; 47 | Renditions current_rendition; 48 | 49 | Framebuffer last_frame; 50 | 51 | FrameState( const Framebuffer &s_last ) 52 | : x(0), y(0), 53 | force_next_put( false ), 54 | str(), cursor_x(0), cursor_y(0), current_rendition( 0 ), 55 | last_frame( s_last ) 56 | { 57 | str.reserve( 1024 ); 58 | } 59 | 60 | void append( const char * s ) { str.append( s ); } 61 | void appendstring( const std::string &s ) { str.append( s ); } 62 | 63 | void append_silent_move( int y, int x ); 64 | }; 65 | 66 | class Display { 67 | private: 68 | static bool ti_flag( const char *capname ); 69 | static int ti_num( const char *capname ); 70 | static const char *ti_str( const char *capname ); 71 | 72 | bool has_ech; /* erase character is part of vt200 but not supported by tmux 73 | (or by "screen" terminfo entry, which is what tmux advertises) */ 74 | 75 | bool has_bce; /* erases result in cell filled with background color */ 76 | 77 | bool has_title; /* supports window title and icon name */ 78 | 79 | int posterize_colors; /* downsample input colors >8 to [0..7] */ 80 | 81 | const char *smcup, *rmcup; /* enter and exit alternate screen mode */ 82 | 83 | void put_cell( bool initialized, FrameState &frame, const Framebuffer &f ) const; 84 | 85 | public: 86 | void downgrade( Framebuffer &f ) const { if ( posterize_colors ) { f.posterize(); } } 87 | 88 | std::string open() const; 89 | std::string close() const; 90 | 91 | std::string new_frame( bool initialized, const Framebuffer &last, const Framebuffer &f ) const; 92 | 93 | Display( bool use_environment ); 94 | }; 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/terminal/terminaldisplayinit.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 | /* This is in its own file because otherwise the ncurses #defines 34 | alias our own variable names. */ 35 | 36 | #include "config.h" 37 | #include "terminaldisplay.h" 38 | 39 | #include 40 | #include 41 | 42 | #if defined HAVE_NCURSESW_CURSES_H 43 | # include 44 | # include 45 | #elif defined HAVE_NCURSESW_H 46 | # include 47 | # include 48 | #elif defined HAVE_NCURSES_CURSES_H 49 | # include 50 | # include 51 | #elif defined HAVE_NCURSES_H 52 | # include 53 | # include 54 | #elif defined HAVE_CURSES_H 55 | # include 56 | # include 57 | #else 58 | # error "SysV or X/Open-compatible Curses header file required" 59 | #endif 60 | #include 61 | #include 62 | 63 | using namespace Terminal; 64 | 65 | bool Display::ti_flag( const char *capname ) 66 | { 67 | int val = tigetflag( const_cast( capname ) ); 68 | if ( val == -1 ) { 69 | throw std::invalid_argument( std::string( "Invalid terminfo boolean capability " ) + capname ); 70 | } 71 | return val; 72 | } 73 | 74 | int Display::ti_num( const char *capname ) 75 | { 76 | int val = tigetnum( const_cast( capname ) ); 77 | if ( val == -2 ) { 78 | throw std::invalid_argument( std::string( "Invalid terminfo numeric capability " ) + capname ); 79 | } 80 | return val; 81 | } 82 | 83 | const char *Display::ti_str( const char *capname ) 84 | { 85 | const char *val = tigetstr( const_cast( capname ) ); 86 | if ( val == (const char *)-1 ) { 87 | throw std::invalid_argument( std::string( "Invalid terminfo string capability " ) + capname ); 88 | } 89 | return val; 90 | } 91 | 92 | Display::Display( bool use_environment ) 93 | : has_ech( true ), has_bce( true ), has_title( true ), posterize_colors( false ), smcup( NULL ), rmcup( NULL ) 94 | { 95 | if ( use_environment ) { 96 | int errret = -2; 97 | int ret = setupterm( (char *)0, 1, &errret ); 98 | 99 | if ( ret != OK ) { 100 | switch ( errret ) { 101 | case 1: 102 | throw std::runtime_error( "Terminal is hardcopy and cannot be used by curses applications." ); 103 | break; 104 | case 0: 105 | throw std::runtime_error( "Unknown terminal type." ); 106 | break; 107 | case -1: 108 | throw std::runtime_error( "Terminfo database could not be found." ); 109 | break; 110 | default: 111 | throw std::runtime_error( "Unknown terminfo error." ); 112 | break; 113 | } 114 | } 115 | 116 | /* check for ECH */ 117 | has_ech = ti_str( "ech" ); 118 | 119 | /* check for BCE */ 120 | has_bce = ti_flag( "bce" ); 121 | 122 | /* Check if we can set the window title and icon name. terminfo does not 123 | have reliable information on this, so we hardcode a whitelist of 124 | terminal type prefixes. This is the list from Debian's default 125 | screenrc, plus "screen" itself (which also covers tmux). */ 126 | static const char * const title_term_types[] = { 127 | "xterm", "rxvt", "kterm", "Eterm", "screen" 128 | }; 129 | 130 | has_title = false; 131 | const char *term_type = getenv( "TERM" ); 132 | if ( term_type ) { 133 | for ( size_t i = 0; 134 | i < sizeof( title_term_types ) / sizeof( const char * ); 135 | i++ ) { 136 | if ( 0 == strncmp( term_type, title_term_types[ i ], 137 | strlen( title_term_types[ i ] ) ) ) { 138 | has_title = true; 139 | break; 140 | } 141 | } 142 | } 143 | 144 | /* posterization disabled because server now only advertises 145 | xterm-256color when client has colors = 256 */ 146 | /* 147 | posterize_colors = ti_num( "colors" ) < 256; 148 | */ 149 | 150 | if ( !getenv( "MOSH_NO_TERM_INIT" ) ) { 151 | smcup = ti_str("smcup"); 152 | rmcup = ti_str("rmcup"); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /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 | #include "terminaluserinput.h" 35 | 36 | using namespace Terminal; 37 | using namespace std; 38 | 39 | string UserInput::input( const Parser::UserByte *act, 40 | bool application_mode_cursor_keys ) 41 | { 42 | act->handled = true; 43 | 44 | /* The user will always be in application mode. If stm is not in 45 | application mode, convert user's cursor control function to an 46 | ANSI cursor control sequence */ 47 | 48 | /* We need to look ahead one byte in the SS3 state to see if 49 | the next byte will be A, B, C, or D (cursor control keys). */ 50 | 51 | switch ( state ) { 52 | case Ground: 53 | if ( act->c == 0x1b ) { /* ESC */ 54 | state = ESC; 55 | } 56 | return string( &act->c, 1 ); 57 | break; 58 | 59 | case ESC: 60 | if ( act->c == 'O' ) { /* ESC O = 7-bit SS3 */ 61 | state = SS3; 62 | return string(); 63 | } else { 64 | state = Ground; 65 | return string( &act->c, 1 ); 66 | } 67 | break; 68 | 69 | case SS3: 70 | state = Ground; 71 | if ( (!application_mode_cursor_keys) 72 | && (act->c >= 'A') 73 | && (act->c <= 'D') ) { 74 | char translated_cursor[ 2 ] = { '[', act->c }; 75 | return string( translated_cursor, 2 ); 76 | } else { 77 | char original_cursor[ 2 ] = { 'O', act->c }; 78 | return string( original_cursor, 2 ); 79 | } 80 | break; 81 | } 82 | 83 | /* This doesn't handle the 8-bit SS3 C1 control, which would be 84 | two octets in UTF-8. Fortunately nobody seems to send this. */ 85 | 86 | assert( false ); 87 | return string(); 88 | } 89 | -------------------------------------------------------------------------------- /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 37 | #include "parseraction.h" 38 | 39 | namespace Terminal { 40 | class UserInput { 41 | public: 42 | enum UserInputState { 43 | Ground, 44 | ESC, 45 | SS3 46 | }; 47 | 48 | private: 49 | UserInputState state; 50 | 51 | public: 52 | UserInput() 53 | : state( Ground ) 54 | {} 55 | 56 | std::string input( const Parser::UserByte *act, 57 | bool application_mode_cursor_keys ); 58 | 59 | bool operator==( const UserInput &x ) const { return state == x.state; } 60 | }; 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/tests/.gitignore: -------------------------------------------------------------------------------- 1 | /ocb-aes 2 | /encrypt-decrypt 3 | -------------------------------------------------------------------------------- /src/tests/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS) 2 | AM_LDFLAGS = $(HARDEN_LDFLAGS) 3 | 4 | check_PROGRAMS = ocb-aes encrypt-decrypt 5 | TESTS = ocb-aes encrypt-decrypt 6 | 7 | ocb_aes_SOURCES = ocb-aes.cc test_utils.cc test_utils.h 8 | ocb_aes_CPPFLAGS = -I$(srcdir)/../crypto -I$(srcdir)/../util 9 | ocb_aes_LDADD = ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(OPENSSL_LIBS) 10 | 11 | encrypt_decrypt_SOURCES = encrypt-decrypt.cc test_utils.cc test_utils.h 12 | encrypt_decrypt_CPPFLAGS = -I$(srcdir)/../crypto -I$(srcdir)/../util 13 | encrypt_decrypt_LDADD = ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(OPENSSL_LIBS) 14 | -------------------------------------------------------------------------------- /src/tests/encrypt-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 | /* Tests the Mosh crypto layer by encrypting and decrypting a bunch of random 34 | messages, interspersed with some random bad ciphertexts which we need to 35 | reject. */ 36 | 37 | #include 38 | 39 | #define __STDC_FORMAT_MACROS 40 | #include 41 | 42 | #include "crypto.h" 43 | #include "prng.h" 44 | #include "fatal_assert.h" 45 | #include "test_utils.h" 46 | 47 | using namespace Crypto; 48 | 49 | PRNG prng; 50 | 51 | const size_t MESSAGE_SIZE_MAX = (2048 - 16); 52 | const size_t MESSAGES_PER_SESSION = 256; 53 | const size_t NUM_SESSIONS = 64; 54 | 55 | bool verbose = false; 56 | 57 | #define NONCE_FMT "%016"PRIx64 58 | 59 | static std::string random_payload( void ) { 60 | const size_t len = prng.uint32() % MESSAGE_SIZE_MAX; 61 | char *buf = new char[len]; 62 | prng.fill( buf, len ); 63 | 64 | std::string payload( buf, len ); 65 | delete [] buf; 66 | return payload; 67 | } 68 | 69 | static void test_bad_decrypt( Session &decryption_session ) { 70 | std::string bad_ct = random_payload(); 71 | 72 | bool got_exn = false; 73 | try { 74 | decryption_session.decrypt( bad_ct ); 75 | } catch ( const CryptoException &e ) { 76 | got_exn = true; 77 | 78 | /* The "bad decrypt" exception needs to be non-fatal, otherwise we are 79 | vulnerable to an easy DoS. */ 80 | fatal_assert( ! e.fatal ); 81 | } 82 | 83 | if ( verbose ) { 84 | hexdump( bad_ct, "bad ct" ); 85 | } 86 | fatal_assert( got_exn ); 87 | } 88 | 89 | /* Generate a single key and initial nonce, then perform some encryptions. */ 90 | static void test_one_session( void ) { 91 | Base64Key key; 92 | Session encryption_session( key ); 93 | Session decryption_session( key ); 94 | 95 | uint64_t nonce_int = prng.uint64(); 96 | 97 | if ( verbose ) { 98 | hexdump( key.data(), 16, "key" ); 99 | } 100 | 101 | for ( size_t i=0; i= 2 && strcmp( argv[ 1 ], "-v" ) == 0 ) { 139 | verbose = true; 140 | } 141 | 142 | for ( size_t i=0; i. 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 | const unsigned char *data = (const unsigned char *) buf; 39 | printf( DUMP_NAME_FMT, name ); 40 | for ( size_t i = 0; i < len; i++ ) { 41 | printf( "%02x", data[ i ] ); 42 | } 43 | printf( "\n" ); 44 | } 45 | 46 | void hexdump( const Crypto::AlignedBuffer &buf, const char *name ) { 47 | hexdump( buf.data(), buf.len(), name ); 48 | } 49 | 50 | void hexdump( const std::string &buf, const char *name ) { 51 | hexdump( buf.data(), buf.size(), name ); 52 | } 53 | -------------------------------------------------------------------------------- /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 "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/util/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_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 utils.h logger.cc logger.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 "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, 2048, "Illegal counterparty input (possible denial of service) in function %s at %s:%d, failed test: %s\n", 45 | function, file, line, expression ); 46 | throw Crypto::CryptoException( buffer ); 47 | } 48 | 49 | #define dos_assert(expr) \ 50 | ((expr) \ 51 | ? (void)0 \ 52 | : dos_detected (#expr, __FILE__, __LINE__, __func__ )) 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /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, "Fatal assertion failure in function %s at %s:%d\nFailed test: %s\n", 42 | function, file, line, expression ); 43 | abort(); 44 | } 45 | 46 | #define fatal_assert(expr) \ 47 | ((expr) \ 48 | ? (void)0 \ 49 | : fatal_error (#expr, __FILE__, __LINE__, __func__ )) 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /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 "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 "locale_utils.h" 47 | 48 | using namespace std; 49 | 50 | const string LocaleVar::str( void ) const 51 | { 52 | if ( name.empty() ) { 53 | return string( "[no charset variables]" ); 54 | } else { 55 | return name + "=" + value; 56 | } 57 | } 58 | 59 | const LocaleVar get_ctype( void ) 60 | { 61 | /* Reimplement the search logic, just for diagnostics */ 62 | if ( const char *all = getenv( "LC_ALL" ) ) { 63 | return LocaleVar( "LC_ALL", all ); 64 | } else if ( const char *ctype = getenv( "LC_CTYPE" ) ) { 65 | return LocaleVar( "LC_CTYPE", ctype ); 66 | } else if ( const char *lang = getenv( "LANG" ) ) { 67 | return LocaleVar( "LANG", lang ); 68 | } else { 69 | return LocaleVar( "", "" ); 70 | } 71 | } 72 | 73 | const char *locale_charset( void ) 74 | { 75 | static const char ASCII_name[] = "US-ASCII"; 76 | 77 | /* Produce more pleasant name of US-ASCII */ 78 | const char *ret = nl_langinfo( CODESET ); 79 | 80 | if ( strcmp( ret, "ANSI_X3.4-1968" ) == 0 ) { 81 | ret = ASCII_name; 82 | } 83 | 84 | return ret; 85 | } 86 | 87 | bool is_utf8_locale( void ) { 88 | /* Verify locale calls for UTF-8 */ 89 | if ( strcmp( locale_charset(), "UTF-8" ) != 0 && 90 | strcmp( locale_charset(), "utf-8" ) != 0 ) { 91 | return 0; 92 | } 93 | return 1; 94 | } 95 | 96 | void set_native_locale( void ) { 97 | /* Adopt native locale */ 98 | if ( NULL == setlocale( LC_ALL, "" ) ) { 99 | int saved_errno = errno; 100 | if ( saved_errno == ENOENT ) { 101 | LocaleVar ctype( get_ctype() ); 102 | fprintf( stderr, "The locale requested by %s isn't available here.\n", ctype.str().c_str() ); 103 | if ( !ctype.name.empty() ) { 104 | fprintf( stderr, "Running `locale-gen %s' may be necessary.\n\n", 105 | ctype.value.c_str() ); 106 | } 107 | } else { 108 | errno = saved_errno; 109 | perror( "setlocale" ); 110 | } 111 | } 112 | } 113 | 114 | void clear_locale_variables( void ) { 115 | unsetenv( "LANG" ); 116 | unsetenv( "LANGUAGE" ); 117 | unsetenv( "LC_CTYPE" ); 118 | unsetenv( "LC_NUMERIC" ); 119 | unsetenv( "LC_TIME" ); 120 | unsetenv( "LC_COLLATE" ); 121 | unsetenv( "LC_MONETARY" ); 122 | unsetenv( "LC_MESSAGES" ); 123 | unsetenv( "LC_PAPER" ); 124 | unsetenv( "LC_NAME" ); 125 | unsetenv( "LC_ADDRESS" ); 126 | unsetenv( "LC_TELEPHONE" ); 127 | unsetenv( "LC_MEASUREMENT" ); 128 | unsetenv( "LC_IDENTIFICATION" ); 129 | unsetenv( "LC_ALL" ); 130 | } 131 | -------------------------------------------------------------------------------- /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 | public: 40 | const std::string name, value; 41 | LocaleVar( const char *s_name, const char *s_value ) 42 | : name( s_name ), value( s_value ) 43 | {} 44 | const std::string str( void ) const; 45 | }; 46 | 47 | const LocaleVar get_ctype( void ); 48 | const char *locale_charset( void ); 49 | bool is_utf8_locale( void ); 50 | void set_native_locale( void ); 51 | void clear_locale_variables( void ); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/util/logger.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007, 2008 by Juliusz Chroboczek 3 | Copyright (c) 2014 by Matthieu Boutier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "logger.h" 29 | 30 | int log_level = 0; 31 | int log_indent_level = 0; 32 | FILE *log_output = NULL; 33 | 34 | void 35 | log_msg(int level, const char *format, ...) 36 | { 37 | int i; 38 | va_list args; 39 | if (UNLIKELY(log_output == NULL)) { 40 | log_output = stderr; 41 | } 42 | if (LOG_GET_LEVEL(log_level) < LOG_GET_LEVEL(level)) 43 | return; 44 | va_start(args, format); 45 | for (i = 0; i < log_indent_level; i ++) 46 | fprintf(log_output, " "); 47 | vfprintf(log_output, format, args); 48 | if (level & LOG_PRINT_ERROR) 49 | fprintf(log_output, ": %s.\n", strerror(errno)); 50 | fflush(log_output); 51 | va_end(args); 52 | } 53 | 54 | void 55 | log_parse_level(const char *string) { 56 | log_level = 0; 57 | while (*string) { 58 | if (*string == 'e') { 59 | log_level |= LOG_ERROR; 60 | } else if (*string == 'd') { 61 | log_level |= LOG_DEBUG; 62 | log_level |= LOG_DEBUG_ALL; 63 | /* There is only one debug level currently. with more, the syntax should be 64 | dcommon, dall, etc: 65 | string ++; 66 | if (*string == 'c') { 67 | log_level |= LOG_DEBUG_COMMON; 68 | } else if (*string == 'a') { 69 | log_level |= LOG_DEBUG_ALL; 70 | } 71 | */ 72 | } else if (*string == 'a') { 73 | log_level |= LOG_MAX; 74 | } else { 75 | break; 76 | } 77 | while (*string && *string != '|') { 78 | string++; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/util/logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 by Matthieu Boutier 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include "utils.h" 25 | 26 | extern int log_level; 27 | extern int log_indent_level; 28 | extern FILE *log_output; 29 | 30 | void log_msg(int level, const char *format, ...) ATTRIBUTE ((format (printf, 2, 3))) COLD; 31 | 32 | /* parse message of the form: "error|debug|dcommon|dall", and set the log level appropriately. */ 33 | void log_parse_level(const char *string); 34 | 35 | /* If debugging is disabled, we want to avoid calling format_address 36 | for every omitted debugging message. So debug is a macro. But 37 | vararg macros are not portable. */ 38 | #if defined NO_DEBUG 39 | 40 | #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L 41 | #define log_dbg(...) do {} while(0) 42 | #elif defined __GNUC__ 43 | #define log_dbg(_args...) do {} while(0) 44 | #else 45 | #define log_dbg if(0) log_msg 46 | #endif 47 | 48 | #define DEBUG(level, statement) 49 | 50 | #else /* !NO_DEBUG */ 51 | 52 | /* log levels */ 53 | #define LOG_ERROR 2 54 | #define LOG_DEBUG 4 55 | #define LOG_MAX 7 56 | #define LOG_GET_LEVEL(x) ((x) & 0xF) 57 | 58 | /* log special flags */ 59 | #define LOG_PRINT_ERROR (1 << 7) 60 | 61 | /* log debug types */ 62 | #define LOG_DEBUG_COMMON ((1 << 8) | LOG_DEBUG) 63 | #define LOG_DEBUG_ALL ((0xFF00) | LOG_DEBUG) 64 | #define LOG_GET_TYPE(x) ((x) & 0xFFF0) 65 | 66 | /* shortcuts */ 67 | #define LOG_PERROR (LOG_PRINT_ERROR | LOG_ERROR) 68 | 69 | #define LOG_DO_DEBUG(level) \ 70 | UNLIKELY((LOG_GET_TYPE(level) & LOG_GET_TYPE(log_level)) && \ 71 | (LOG_DEBUG <= LOG_GET_LEVEL(log_level))) 72 | 73 | #define DEBUG(level, statement) \ 74 | if(LOG_DO_DEBUG(level)) {statement;} 75 | 76 | #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L 77 | #define log_dbg(level, ...) \ 78 | do { \ 79 | if(LOG_DO_DEBUG(level)) log_msg(level, __VA_ARGS__); \ 80 | } while(0) 81 | #elif defined __GNUC__ 82 | #define log_dbg(level, _args...) \ 83 | do { \ 84 | if(LOG_DO_DEBUG(level)) log_msg(level, _args); \ 85 | } while(0) 86 | #else 87 | #warning No debug available. 88 | static inline void log_dbg(int level, const char *format, ...) { return; } 89 | #endif 90 | 91 | #endif /* NO_DEBUG */ 92 | -------------------------------------------------------------------------------- /src/util/pty_compat.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 "config.h" 34 | 35 | #if !defined(HAVE_FORKPTY) || !defined(HAVE_CFMAKERAW) 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "pty_compat.h" 46 | 47 | #ifndef HAVE_FORKPTY 48 | pid_t my_forkpty( int *amaster, char *name, 49 | const struct termios *termp, 50 | const struct winsize *winp ) 51 | { 52 | /* For Solaris and AIX */ 53 | int master, slave; 54 | char *slave_name; 55 | pid_t pid; 56 | 57 | #ifdef _AIX 58 | #define PTY_DEVICE "/dev/ptc" 59 | #else 60 | #define PTY_DEVICE "/dev/ptmx" 61 | #endif 62 | 63 | master = open( PTY_DEVICE, O_RDWR | O_NOCTTY ); 64 | if ( master < 0 ) { 65 | perror( "open(" PTY_DEVICE ")" ); 66 | return -1; 67 | } 68 | 69 | if ( grantpt( master ) < 0 ) { 70 | perror( "grantpt" ); 71 | close( master ); 72 | return -1; 73 | } 74 | 75 | if ( unlockpt(master) < 0 ) { 76 | perror( "unlockpt" ); 77 | close( master ); 78 | return -1; 79 | } 80 | 81 | slave_name = ptsname( master ); 82 | if ( slave_name == NULL ) { 83 | perror( "ptsname" ); 84 | close( master ); 85 | return -1; 86 | } 87 | 88 | slave = open( slave_name, O_RDWR | O_NOCTTY ); 89 | if ( slave < 0 ) { 90 | perror( "open(slave)" ); 91 | close( master ); 92 | return -1; 93 | } 94 | 95 | #ifndef _AIX 96 | if ( ioctl(slave, I_PUSH, "ptem") < 0 || 97 | ioctl(slave, I_PUSH, "ldterm") < 0 ) { 98 | perror( "ioctl(I_PUSH)" ); 99 | close( slave ); 100 | close( master ); 101 | return -1; 102 | } 103 | #endif 104 | 105 | if ( amaster != NULL ) 106 | *amaster = master; 107 | 108 | if ( name != NULL) 109 | strcpy( name, slave_name ); 110 | 111 | if ( termp != NULL ) { 112 | if ( tcsetattr( slave, TCSAFLUSH, termp ) < 0 ) { 113 | perror( "tcsetattr" ); 114 | exit( 1 ); 115 | } 116 | } 117 | 118 | // we need to set initial window size, or TIOCGWINSZ fails 119 | struct winsize w; 120 | w.ws_row = 25; 121 | w.ws_col = 80; 122 | w.ws_xpixel = 0; 123 | w.ws_ypixel = 0; 124 | if ( ioctl( slave, TIOCSWINSZ, &w) < 0 ) { 125 | perror( "ioctl TIOCSWINSZ" ); 126 | exit( 1 ); 127 | } 128 | if ( winp != NULL ) { 129 | if ( ioctl( slave, TIOCGWINSZ, winp ) < 0 ) { 130 | perror( "ioctl TIOCGWINSZ" ); 131 | exit( 1 ); 132 | } 133 | } 134 | 135 | pid = fork(); 136 | switch ( pid ) { 137 | case -1: /* Error */ 138 | perror( "fork()" ); 139 | return -1; 140 | case 0: /* Child */ 141 | if ( setsid() < 0 ) 142 | perror( "setsid" ); 143 | #ifdef TIOCSCTTY 144 | if ( ioctl( slave, TIOCSCTTY, NULL ) < 0 ) { 145 | perror( "ioctl" ); 146 | return -1; 147 | } 148 | #else 149 | { 150 | int dummy_fd; 151 | dummy_fd = open (slave_name, O_RDWR); 152 | if (dummy_fd < 0) { 153 | perror( "open(slave_name)" ); 154 | return -1; 155 | } 156 | close (dummy_fd); 157 | } 158 | #endif /* TIOCSCTTY */ 159 | close( master ); 160 | dup2( slave, STDIN_FILENO ); 161 | dup2( slave, STDOUT_FILENO ); 162 | dup2( slave, STDERR_FILENO ); 163 | return 0; 164 | default: /* Parent */ 165 | close( slave ); 166 | return pid; 167 | } 168 | } 169 | #endif 170 | 171 | #ifndef HAVE_CFMAKERAW 172 | void my_cfmakeraw( struct termios *termios_p ) 173 | { 174 | termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 175 | | INLCR | IGNCR | ICRNL | IXON); 176 | termios_p->c_oflag &= ~OPOST; 177 | termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 178 | termios_p->c_cflag &= ~(CSIZE | PARENB); 179 | termios_p->c_cflag |= CS8; 180 | 181 | termios_p->c_cc[VMIN] = 1; // read() is satisfied after 1 char 182 | termios_p->c_cc[VTIME] = 0; // No timer 183 | } 184 | #endif 185 | #endif 186 | -------------------------------------------------------------------------------- /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 "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, 46 | const struct termios *termp, 47 | const struct winsize *winp ); 48 | 49 | void my_cfmakeraw( struct termios *termios_p ); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /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 "select.h" 34 | 35 | fd_set Select::dummy_fd_set; 36 | 37 | sigset_t Select::dummy_sigset; 38 | 39 | void Select::handle_signal( int signum ) 40 | { 41 | fatal_assert( signum >= 0 ); 42 | fatal_assert( signum <= MAX_SIGNAL_NUMBER ); 43 | 44 | Select &sel = get_instance(); 45 | sel.got_signal[ signum ] = 1; 46 | sel.got_any_signal = 1; 47 | } 48 | -------------------------------------------------------------------------------- /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 | #include 36 | 37 | #include "swrite.h" 38 | 39 | int swrite( int fd, const char *str, ssize_t len ) 40 | { 41 | ssize_t total_bytes_written = 0; 42 | ssize_t bytes_to_write = ( len >= 0 ) ? len : (ssize_t) strlen( str ); 43 | while ( total_bytes_written < bytes_to_write ) { 44 | ssize_t bytes_written = write( fd, str + total_bytes_written, 45 | bytes_to_write - total_bytes_written ); 46 | if ( bytes_written <= 0 ) { 47 | perror( "write" ); 48 | return -1; 49 | } else { 50 | total_bytes_written += bytes_written; 51 | } 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /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.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 "config.h" 34 | 35 | #include "timestamp.h" 36 | 37 | #include 38 | 39 | #if HAVE_CLOCK_GETTIME 40 | #include 41 | #elif HAVE_MACH_ABSOLUTE_TIME 42 | #include 43 | #elif HAVE_GETTIMEOFDAY 44 | #include 45 | #include 46 | #endif 47 | 48 | static uint64_t millis_cache = -1; 49 | 50 | uint64_t frozen_timestamp( void ) 51 | { 52 | if ( millis_cache == uint64_t( -1 ) ) { 53 | freeze_timestamp(); 54 | } 55 | 56 | return millis_cache; 57 | } 58 | 59 | void freeze_timestamp( void ) 60 | { 61 | #if HAVE_CLOCK_GETTIME 62 | struct timespec tp; 63 | 64 | if ( clock_gettime( CLOCK_MONOTONIC, &tp ) < 0 ) { 65 | /* did not succeed */ 66 | } else { 67 | uint64_t millis = tp.tv_nsec / 1000000; 68 | millis += uint64_t( tp.tv_sec ) * 1000; 69 | 70 | millis_cache = millis; 71 | return; 72 | } 73 | #elif HAVE_MACH_ABSOLUTE_TIME 74 | static mach_timebase_info_data_t s_timebase_info; 75 | static double absolute_to_millis; 76 | 77 | if (s_timebase_info.denom == 0) { 78 | mach_timebase_info(&s_timebase_info); 79 | absolute_to_millis = 1e-6 * s_timebase_info.numer / s_timebase_info.denom; 80 | } 81 | 82 | // NB: mach_absolute_time() returns "absolute time units" 83 | // We need to apply a conversion to get milliseconds. 84 | millis_cache = mach_absolute_time() * absolute_to_millis; 85 | return; 86 | #elif HAVE_GETTIMEOFDAY 87 | // NOTE: If time steps backwards, timeouts may be confused. 88 | struct timeval tv; 89 | if ( gettimeofday(&tv, NULL) ) { 90 | perror( "gettimeofday" ); 91 | } else { 92 | uint64_t millis = tv.tv_usec / 1000; 93 | millis += uint64_t( tv.tv_sec ) * 1000; 94 | 95 | millis_cache = millis; 96 | return; 97 | } 98 | #else 99 | # error "Don't know how to get a timestamp on this platform" 100 | #endif 101 | } 102 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/util/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007, 2008 by Juliusz Chroboczek 3 | Copyright (c) 2013 by Matthieu Boutier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | 24 | #ifndef UTIL_H 25 | #define UTIL_H 26 | 27 | #if defined(__GNUC__) && (__GNUC__ >= 3) 28 | #define ATTRIBUTE(x) __attribute__ (x) 29 | #define LIKELY(_x) __builtin_expect(!!(_x), 1) 30 | #define UNLIKELY(_x) __builtin_expect(!!(_x), 0) 31 | #else 32 | #define ATTRIBUTE(x) /**/ 33 | #define LIKELY(_x) !!(_x) 34 | #define UNLIKELY(_x) !!(_x) 35 | #endif 36 | 37 | #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) 38 | #define COLD __attribute__ ((cold)) 39 | #else 40 | #define COLD /**/ 41 | #endif 42 | 43 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) 44 | #define MIN(x,y) ((x) < (y) ? (x) : (y)) 45 | 46 | #endif /* UTIL_H */ 47 | --------------------------------------------------------------------------------