Fix typos
[TortoiseGit.git] / src / TortoisePlink / Windows / sharing.c
blobbce1ea1e587cb251dfda6dc67ad7a14e4c87e889
1 /*
2 * Windows implementation of SSH connection-sharing IPC setup.
3 */
5 #include <stdio.h>
6 #include <assert.h>
8 #include "tree234.h"
9 #include "putty.h"
10 #include "network.h"
11 #include "proxy/proxy.h"
12 #include "ssh.h"
14 #include "cryptoapi.h"
15 #include "security-api.h"
17 #define CONNSHARE_PIPE_PREFIX "\\\\.\\pipe\\putty-connshare"
18 #define CONNSHARE_MUTEX_PREFIX "Local\\putty-connshare-mutex"
20 static char *make_name(const char *prefix, const char *name)
22 char *username, *retname;
24 username = get_username();
25 retname = dupprintf("%s.%s.%s", prefix, username, name);
26 sfree(username);
28 return retname;
31 int platform_ssh_share(const char *pi_name, Conf *conf,
32 Plug *downplug, Plug *upplug, Socket **sock,
33 char **logtext, char **ds_err, char **us_err,
34 bool can_upstream, bool can_downstream)
36 char *name, *mutexname, *pipename;
37 HANDLE mutex;
38 Socket *retsock;
41 * Transform the platform-independent version of the connection
42 * identifier into the obfuscated version we'll use for our
43 * Windows named pipe and mutex. A side effect of doing this is
44 * that it also eliminates any characters illegal in Windows pipe
45 * names.
47 name = capi_obfuscate_string(pi_name);
48 if (!name) {
49 *logtext = dupprintf("Unable to call CryptProtectMemory: %s",
50 win_strerror(GetLastError()));
51 return SHARE_NONE;
55 * Make a mutex name out of the connection identifier, and lock it
56 * while we decide whether to be upstream or downstream.
58 mutexname = make_name(CONNSHARE_MUTEX_PREFIX, name);
59 mutex = lock_interprocess_mutex(mutexname, logtext);
60 if (!mutex) {
61 sfree(mutexname);
62 sfree(name);
63 return SHARE_NONE;
66 pipename = make_name(CONNSHARE_PIPE_PREFIX, name);
68 *logtext = NULL;
70 if (can_downstream) {
71 retsock = new_named_pipe_client(pipename, downplug);
72 if (sk_socket_error(retsock) == NULL) {
73 sfree(*logtext);
74 *logtext = pipename;
75 *sock = retsock;
76 sfree(name);
77 unlock_interprocess_mutex(mutex);
78 return SHARE_DOWNSTREAM;
80 sfree(*ds_err);
81 *ds_err = dupprintf("%s: %s", pipename, sk_socket_error(retsock));
82 sk_close(retsock);
85 if (can_upstream) {
86 retsock = new_named_pipe_listener(pipename, upplug);
87 if (sk_socket_error(retsock) == NULL) {
88 sfree(*logtext);
89 *logtext = pipename;
90 *sock = retsock;
91 sfree(name);
92 ReleaseMutex(mutex);
93 CloseHandle(mutex);
94 return SHARE_UPSTREAM;
96 sfree(*us_err);
97 *us_err = dupprintf("%s: %s", pipename, sk_socket_error(retsock));
98 sk_close(retsock);
101 /* One of the above clauses ought to have happened. */
102 assert(*logtext || *ds_err || *us_err);
104 sfree(pipename);
105 sfree(name);
106 ReleaseMutex(mutex);
107 CloseHandle(mutex);
108 return SHARE_NONE;
111 void platform_ssh_share_cleanup(const char *name)