Skip to content
This repository was archived by the owner on Jun 15, 2020. It is now read-only.

Commit a2c7502

Browse files
committed
Initial working version.
1 parent dce1666 commit a2c7502

16 files changed

+1560
-111
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,6 @@ __pycache__/
262262

263263
# Ubuntu headers (for IntelliSense)
264264
/linux/include
265+
266+
# Release packages
267+
/*.zip

COPYING

+674
Large diffs are not rendered by default.

COPYING.PuTTY

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Part of weasel-pageant is derived from the PuTTY program, whose original
2+
license is reproduced below.
3+
4+
5+
PuTTY is copyright 1997-2011 Simon Tatham.
6+
7+
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
8+
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
9+
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
10+
Kuhn, Colin Watson, and CORE SDI S.A.
11+
12+
Permission is hereby granted, free of charge, to any person
13+
obtaining a copy of this software and associated documentation files
14+
(the "Software"), to deal in the Software without restriction,
15+
including without limitation the rights to use, copy, modify, merge,
16+
publish, distribute, sublicense, and/or sell copies of the Software,
17+
and to permit persons to whom the Software is furnished to do so,
18+
subject to the following conditions:
19+
20+
The above copyright notice and this permission notice shall be
21+
included in all copies or substantial portions of the Software.
22+
23+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+
NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
27+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
weasel-pageant
2+
--------------
3+
4+
`weasel-pageant` allows you to use SSH keys held by [PuTTY's](https://www.chiark.greenend.org.uk/~sgtatham/putty/)
5+
Pageant "daemon" (or compatible, such as the version of Pageant included in
6+
[PuTTY-CAC](https://github.com/NoMoreFood/putty-cac) or the SSH agent mode in
7+
[Gpg4win](https://www.gpg4win.org/)) from inside the
8+
[Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/about).
9+
10+
The source (and this documentation) is heavily based on
11+
[`ssh-pageant`](https://github.com/cuviper/ssh-pageant) 1.4 by Josh Stone, which allows
12+
interacting with Pageant from Cygwin/MSYS programs.
13+
14+
`weasel-pageant` works like `ssh-agent`, except that it leaves the key storage to
15+
PuTTY's Pageant. It sets up an authentication socket and prints the environment
16+
variables, which allows the OpenSSH client to use it. It works by executing from the
17+
WSL side a Win32 helper program which interfaces with Pageant and communicating with
18+
it through pipes.
19+
20+
It is probably the most useful if your SSH keys can't be copied to the WSL environment,
21+
such as when using a smart card for SSH authentication. Both Pageant-CAC and Gpg4win
22+
have been tested (note that when using Gpg4win, only the SSH authentication functionality
23+
will be forwarded; the Windows-side `gpg-agent` will not be available on the WSL side).
24+
25+
**SECURITY NOTICE:** All the usual security caveats applicable to WSL apply here too.
26+
Most importantly, all interaction with the Win32 world happens with the credentials of
27+
the user who started the WSL environment. In practice, *if you allow someone else to
28+
log in to your WSL environment remotely, they can access the SSH keys stored in your
29+
Pageant with `weasel-pageant`.* This is a fundamental part of how WSL works; if you
30+
are not sure of what you're doing, do not allow remote access to your WSL enviroment
31+
(i.e. by starting an SSH server).
32+
33+
**COMPATIBILITY NOTICE:** `weasel-pageant` does not, and will never work on
34+
a version of Windows 10 older than 1703 ("Creators Update"), because
35+
it requires the new [Windows/Ubuntu interoperability support](https://blogs.msdn.microsoft.com/wsl/2016/10/19/windows-and-ubuntu-interoperability/)
36+
feature shipped with version 1703 (compatibility with older Insider
37+
builds is unclear). Presumably it should work with newer Insider builds,
38+
but has not been tested on anything more recent than build 15063.413.
39+
40+
If you are still using Anniversary Update, you may be able to use the (unrelated)
41+
[wsl-ssh-pageant](https://github.com/benpye/wsl-ssh-pageant).
42+
43+
## Installation
44+
45+
### From binaries
46+
47+
Download the zip file from the releases page and unpack it in a convenient location
48+
*on the Windows part of your drive*. Because WSL can only execute Win32 binaries from
49+
`drvfs` locations, `weasel-pageant` *will not work* if unpacked inside the WSL
50+
filesystem (onto an `lxfs` mount). (Advanced users may place only `helper.exe` on
51+
`drvfs`, but in general it is easier to keep the pieces together.)
52+
53+
### From source
54+
55+
A VS2017 project is included. You will need the "Desktop development with C++" and
56+
"Linux development with C++" features.
57+
58+
1. In VS2017, set up a connection to your WSL environment (or a remote Linux machine)
59+
in Options → Cross Platform → Connection Manager.
60+
61+
2. Optional: If you intend to work on the Linux sources, copy the contents of
62+
`/usr/include` into `weasel-pageant/include` under the project directory.
63+
This is not required for the build, but will make Intellisense more useful.
64+
65+
3. Hit Build Solution and both the Linux executable and the Win32 helper will be built.
66+
67+
If you want to create a binary package, you can use the `create_pkg.py` script
68+
at the root of the project. This should work with Python 3.4 or newer on either
69+
Windows or Linux.
70+
71+
Alternatively you can build the Linux executable directly on Linux and only use
72+
Visual Studio for the Win32 helper (no Makefile or similar is supplied at the moment).
73+
In theory the helper should be buildable with MinGW-w64 for a fully Linux-based
74+
build, but this has not been tested.
75+
76+
The release binaries have been built with VS2017 15.3.0 Preview 2.0.
77+
78+
## Usage
79+
80+
Using `weasel-pageant` is generally similar to using `ssh-agent` on Linux and
81+
similar operating systems.
82+
83+
1. Ensure that PuTTY's Pageant is running (and holds your SSH keys).
84+
* ssh-pageant does not start Pageant itself.
85+
* Recommended: Add Pageant to your Windows startup/Autostart configuration
86+
so it is always available.
87+
88+
2. Edit your `~/.bashrc` (or `~/.bash_profile`) to add the following:
89+
90+
eval $(<location where you unpacked the zip>/weasel-pageant -r -a "/tmp/.weasel-pageant-$USERNAME")
91+
92+
To explain:
93+
94+
* This leverages the `-r`/`--reuse` option in combination with `-a SOCKET`,
95+
which will only start a new daemon if the specified path does not accept connections
96+
already. If the socket appears to be active, it will just set `SSH_AUTH_SOCK` and exit.
97+
98+
* The exact path used for `-a` is arbitrary. The socket will be created
99+
with only user-accessible permissions, but you may still want to use a more
100+
private path than shown above if multiple users can access your WSL instance.
101+
102+
* When using this, the `weasel-pageant` daemon and its helper process `helper.exe`
103+
remains active (both will be visible in the Windows task manager). You should not
104+
kill these processes, since open shells might still be using the socket.
105+
106+
* Using `eval` will set the environment variables in the current shell.
107+
By default, `weasel-pageant` tries to detect the current shell and output
108+
appropriate commands. If detection fails, then use the `-S SHELL` option
109+
to define a shell type manually.
110+
111+
3. Restart your shell or type (when using bash) `. ~/.bashrc`. Typing `ssh-add -l`
112+
should now list the keys you have registered in Pageant.
113+
114+
## Options
115+
116+
`weasel-pageant` aims to be compatible with `ssh-agent` options, with a few extras:
117+
118+
$ weasel-pageant -h
119+
Usage: weasel-pageant [options] [command [arg ...]]
120+
Options:
121+
-h, --help Show this help.
122+
-v, --version Display version information.
123+
-c Generate C-shell commands on stdout.
124+
-s Generate Bourne shell commands on stdout.
125+
-S SHELL Generate shell command for "bourne", "csh", or "fish".
126+
-k Kill the current weasel-pageant.
127+
-d Enable debug mode.
128+
-q Enable quiet mode.
129+
-a SOCKET Create socket on a specific path.
130+
-r, --reuse Allow to reuse an existing -a SOCKET.
131+
-H, --helper Path to the Win32 helper binary (default: /mnt/c/Program Files/weasel-pageant/helper.exe).
132+
-t TIME Limit key lifetime in seconds (not supported by Pageant).
133+
134+
By default, the Win32 helper will be searched for in the same directory where `weasel-pageant`
135+
is stored. If you have placed it elsewhere, the `-H` flag can be used to set the location.
136+
137+
## Known issues
138+
139+
* The Win32 helper cannot be restarted if it's killed or crashes. There appears to be a bug
140+
in WSL that causes pipes passed to Win32 executables to be unusable after some point
141+
in program execution (possibly related to forking processes or opening sockets). Currently,
142+
`weasel-pageant` will exit if it detects that the helper has exited.
143+
144+
## Uninstallation
145+
146+
To uninstall, just remove the extracted files and any modifications you made
147+
to your shell initialization files (i.e. `.bashrc`).
148+
149+
## Version History
150+
151+
* 2017-06-25: 1.0 - Initial release.
152+
153+
## Contributions
154+
155+
Please send bug reports using Github's Issues feature. Pull requests are also
156+
welcome, though if you intend to do major changes it's recommended to open an
157+
issue first.
158+
159+
------------------------------------------------------------------------------
160+
Copyright 2017 Valtteri Vuorikoski
161+
162+
Based on `ssh-pageant`, copyright (C) 2009-2014 Josh Stone
163+
164+
Licensed under the GNU GPL version 3 or later, http://gnu.org/licenses/gpl.html
165+
166+
This is free software: you are free to change and redistribute it.
167+
There is NO WARRANTY, to the extent permitted by law.
168+
169+
See the `COPYING` file for license details.
170+
Part of `weasel-pageant` is derived from the PuTTY program, whose original license is
171+
in the file `COPYING.PuTTY`.

create_pkg.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# weasel-pageant packaging script.
3+
#
4+
# Copyright 2017 Valtteri Vuorikoski
5+
#
6+
# This file is part of weasel-pageant, and is free software: you can
7+
# redistribute it and/or modify it under the terms of the GNU General
8+
# Public License as published by the Free Software Foundation, either
9+
# version 3 of the License, or (at your option) any later version.
10+
#
11+
12+
import sys
13+
import zipfile
14+
15+
CURRENT_VERSION = '1.0'
16+
17+
try:
18+
reltype = sys.argv[1]
19+
except IndexError:
20+
reltype = 'release'
21+
22+
if reltype not in ('release', 'debug'):
23+
print('usage: create_pkg release|debug', file=sys.stderr)
24+
sys.exit(1)
25+
26+
manifest = [
27+
'COPYING',
28+
'COPYING.PuTTY',
29+
'README.md'
30+
]
31+
32+
if reltype == 'release':
33+
dirname = 'weasel-pageant-%s' % CURRENT_VERSION
34+
manifest.extend([
35+
'x64/Release/helper.exe',
36+
'linux/bin/x64/Release/weasel-pageant'
37+
])
38+
else:
39+
dirname = 'weasel-pageant-%s-%s' % (reltype, CURRENT_VERSION)
40+
manifest.extend([
41+
'x64/Debug/helper.exe',
42+
'linux/bin/x64/Debug/weasel-pageant'
43+
])
44+
45+
outname = dirname + '.zip'
46+
zipf = zipfile.ZipFile(outname, 'w', compression=zipfile.ZIP_DEFLATED)
47+
48+
def basename(x):
49+
return x.rsplit('/')[-1]
50+
51+
for fname in manifest:
52+
zipf.write(fname, '%s/%s' % (dirname, basename(fname)))
53+
54+
zipf.close()
55+
sys.exit(0)

linux/common.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
/*
4+
* weasel-pageant Linux/Win32 common header.
5+
* Copyright 2017 Valtteri Vuorikoski
6+
* Based on ssh-pageant, copyright 2009,2014 Josh Stone
7+
*
8+
* This file is part of weasel-pageant, and is free software: you can
9+
* redistribute it and/or modify it under the terms of the GNU General
10+
* Public License as published by the Free Software Foundation, either
11+
* version 3 of the License, or (at your option) any later version.
12+
*/
13+
14+
// This file may be included from both the Linux and the Win32 code.
15+
16+
#define AGENT_MAX_MSGLEN 8192
17+
18+
#define WSLP_CHILD_FLAG_DEBUG (1 << 0)
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
static inline uint32_t msglen(const void *p) {
25+
return 4 + ntohl(*(const uint32_t *)p);
26+
}
27+
28+
#ifdef __cplusplus
29+
};
30+
#endif

linux/linux.vcxproj

+19-1
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,31 @@
6969
<RemoteCCompileToolExe>gcc</RemoteCCompileToolExe>
7070
<RemoteLdToolExe>gcc</RemoteLdToolExe>
7171
<IncludePath>$(IncludePath);$(ProjectDir)include\x86_64-linux-gnu;$(ProjectDir)include;$(ISenseIncludePath)</IncludePath>
72+
<TargetName>weasel-pageant</TargetName>
73+
<TargetExt />
74+
</PropertyGroup>
75+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
76+
<IncludePath>$(IncludePath);$(ProjectDir)include\x86_64-linux-gnu;$(ProjectDir)include;$(ISenseIncludePath)</IncludePath>
77+
<TargetName>weasel-pageant</TargetName>
78+
<TargetExt />
7279
</PropertyGroup>
7380
<ItemGroup>
7481
<ClCompile Include="main.c" />
7582
</ItemGroup>
83+
<ItemGroup>
84+
<ClInclude Include="common.h" />
85+
</ItemGroup>
86+
<ItemGroup>
87+
<None Include="..\README.md" />
88+
</ItemGroup>
7689
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
7790
<ClCompile>
78-
<PreprocessorDefinitions>_GNU_SOURCE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
91+
<PreprocessorDefinitions>_GNU_SOURCE=1</PreprocessorDefinitions>
92+
</ClCompile>
93+
</ItemDefinitionGroup>
94+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
95+
<ClCompile>
96+
<PreprocessorDefinitions>_GNU_SOURCE=1</PreprocessorDefinitions>
7997
</ClCompile>
8098
</ItemDefinitionGroup>
8199
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

0 commit comments

Comments
 (0)