tunnel via multiple hops in SSH

  • I am working locally on localhost
  • host1 is accessible to localhost
  • host2 only accepts connections from host1
  • I need to create a tunnel from localhost to host2

You basically have three possibilities:

  1. Tunnel from localhost to host1:
    ssh -L 9999:host2:1234 -N host1
    

    As noted above, the connection from host1 to host2 will not be secured.

  2. Tunnel from localhost to host1 and from host1 to host2:
    ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
    

    This will open a tunnel from localhost to host1 and another tunnel from host1 to host2. However the port 9999 to host2:1234 can be used by anyone on host1. This may or may not be a problem.

  3. Tunnel from localhost to host1 and from localhost to host2:
    ssh -L 9998:host2:22 -N host1
    ssh -L 9999:localhost:1234 -N -p 9998 localhost
    

    This will open a tunnel from localhost to host1 through which the SSH service on host2 can be used. Then a second tunnel is opened from localhost to host2 through the first tunnel.

Normally, I’d go with option 1. If the connection from host1 to host2 needs to be secured, go with option 2. Option 3 is mainly useful to access a service on host2 that is only reachable from host2 itself.

References
https://superuser.com/questions/96489/an-ssh-tunnel-via-multiple-hops

Bind DataContext to ViewModel in WPF

Last Updated on February 8, 2024

<Window x:Class="desktop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:local="clr-namespace:desktop.viewmodel"
        Title="Monitoring" Height="350" Width="525" Loaded="MainWindow_OnLoaded" WindowState="Maximized">
    <Window.DataContext>
        <local:MainWindowViewModel x:Key="ViewModel" />
    </Window.DataContext>
    <DockPanel>
        <telerik:RadMenu Name="MenuMain" VerticalAlignment="Top" DockPanel.Dock="Top">
            <telerik:RadMenuItem Header="Item 1">
                <telerik:RadMenuItem Header="SubItem 1" />
                <telerik:RadMenuItem Header="SubItem 2" />
            </telerik:RadMenuItem>
            <telerik:RadMenuItem Header="Item 2" />
        </telerik:RadMenu>
        <telerik:RadBusyIndicator IsBusy="{Binding  Path=IsBusyIndicatorBusy}">
            <Frame Name="FrameMain" NavigationUIVisibility="Hidden" />
        </telerik:RadBusyIndicator>

    </DockPanel>
</Window>
public partial class MainWindow : Window
    {
        public MainWindowViewModel ViewModel { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            ViewModel = (MainWindowViewModel) DataContext;
        }
     }

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
    {
        if(!EqualityComparer<T>.Default.Equals(field, newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
        return false;
    }
}

ViewModel

using System.ComponentModel;
using System.Runtime.CompilerServices;
using desktop.Annotations;
using Telerik.Windows.Controls;

namespace desktop.viewmodel
{
    public class MainWindowViewModel : ViewModelBase
    {

        private bool _isBusyIndicatorBusy = false;

        public bool IsBusyIndicatorBusy
        {
            get => _isBusyIndicatorBusy;
            set
            {
                _isBusyIndicatorBusy = value;
                SetProperty(ref _isBusyIndicatorBusy , value);
            }
        }
    }
}

References
https://stackoverflow.com/questions/25267070/setting-datacontext-of-elements-inside-xaml
https://intellitect.com/blog/getting-started-model-view-viewmodel-mvvm-pattern-using-windows-presentation-framework-wpf/

Bind DataContext to Current Window in WPF

XAML way

DataContext="{Binding RelativeSource={RelativeSource Self}}"
DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}}">
<UserControl ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>

C# way

using System;
using System.Windows;

namespace WpfTutorialSamples.DataBinding
{
    public partial class DataContextSample : Window
    {
        public DataContextSample()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }
}

References
https://stackoverflow.com/questions/12430615/datacontext-and-binding-self-as-relativesource
https://wpf-tutorial.com/data-binding/using-the-datacontext/
https://stackoverflow.com/questions/11995318/how-do-i-bind-to-relativesource-self
https://stackoverflow.com/questions/20420001/how-to-set-datacontext-to-self

WPF Start-up

StartupUri Property

<Application x:Class="StartupShutdownDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
          
    </Application.Resources>
</Application>

OnStartup

protected override async void OnStartup(StartupEventArgs e)
{
await Init();
}

References
http://www.blackwasp.co.uk/WPFStartupShutdown.aspx

Serialize objects in file with protobuf in C#

Install-Package protobuf-net

Decorate your classes

[ProtoContract]
class Person {
    [ProtoMember(1)]
    public int Id {get;set;}
    [ProtoMember(2)]
    public string Name {get;set;}
    [ProtoMember(3)]
    public Address Address {get;set;}
}
[ProtoContract]
class Address {
    [ProtoMember(1)]
    public string Line1 {get;set;}
    [ProtoMember(2)]
    public string Line2 {get;set;}
}

Serialize your data

var person = new Person {
    Id = 12345, Name = "Fred",
    Address = new Address {
        Line1 = "Flat 1",
        Line2 = "The Meadows"
    }
};
using(var file = new FileStream(path, FileMode.Truncate)) {
    Serializer.Serialize(file, person);
    file.SetLength(file.Position);
}
if (!File.Exists(Statics.UserProtobufFile))
{
    using (var file = new FileStream(Statics.UserProtobufFile, FileMode.Create))
    {
        Serializer.Serialize(file, Statics.User);
        file.SetLength(file.Position);
    }
}
else
{
    using (var file = new FileStream(Statics.UserProtobufFile, FileMode.Truncate))
    {
        Serializer.Serialize(file, Statics.User);
        file.SetLength(file.Position);
    }
}

Deserialize your data

Person newPerson;
using (var file = File.OpenRead("person.bin")) {
    newPerson = Serializer.Deserialize<Person>(file);
}

References
https://github.com/protobuf-net/protobuf-net
https://stackoverflow.com/questions/20369302/how-to-serialize-several-objects-in-one-file-in-c-sharp-with-protobuf
https://stackoverflow.com/questions/2152978/using-protobuf-net-i-suddenly-got-an-exception-about-an-unknown-wire-type