pipe2me-client 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8968003f722e5a557b48c68a931a956df97cd349
4
- data.tar.gz: d8092a7be2cfcb52ca99c93fb507aa4ffb3f41ce
3
+ metadata.gz: 8eceaa5c69187b15f7b43b0fe2cdbe1dd9b7281f
4
+ data.tar.gz: ca812510cb4937691876f1fc8b5642b50cea853d
5
5
  SHA512:
6
- metadata.gz: fe87297cd767ce05ba03e4e37b63ae9eb4a90d24c9d7275a6cfc7744b5b262223e7a2f1f0b982eb1287e564854722d81cd92066483b54e2b1e056942282142e3
7
- data.tar.gz: 9a48bf4a510a9bf8145492c52861e27619fbba879a934c5bab9a694e546b4dc7360894f18143da48e1a95cabf9cf4f182234aab3462bbe6052abdedacb3ff1d6
6
+ metadata.gz: ee65b0e72ff5c66bb7bca14a7c2724a0e7f1717b33696d0b9aaf1aa1f7a87b1a8ea78cffab3f4d08df416a6dcf17c1f72d13db195a3be7037da69194193dedfe
7
+ data.tar.gz: 7fa92f1490c22365e4a8ca87f0ed4480429923694ba24d6c2ac897db6f37162ca64b1fc7493b67698342951d881364386aa6761d67afcc97cd958f127247dd90
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # pipe2me client
2
2
 
3
- This is the ruby client for the pipe2me server package.
3
+ This is the ruby client for the pipe2me server package.
4
4
  The pipe2me client lets you publish local services to the public internet
5
5
  with the help and orchestration of a pipe2me server. For more details
6
6
  see [pipe2me](https://github.com/kinko/pipe2me)
@@ -15,7 +15,7 @@ To install it run
15
15
  sudo cp doc/pipe2me.1 /usr/local/share/man/man1
16
16
 
17
17
  If you are managing a box with a system-wide ruby installation you must install
18
- it via
18
+ it via
19
19
 
20
20
  sudo gem install pipe2me-client
21
21
 
@@ -25,13 +25,13 @@ Verify the installation with
25
25
 
26
26
  ## Usage
27
27
 
28
- Mini-example: This registers two tunnels with a single hostname for
29
- two services on localhost (http on port 9090, https on port 9091).
28
+ Mini-example: This registers two tunnels with a single hostname for
29
+ two services on localhost (http on port 9090, https on port 9091).
30
30
 
31
31
  <pre>
32
32
  # Setup tunnels. This responds with the domain name
33
33
  &gt; <b>pipe2me setup --protocols http,https \
34
- --server http://test.pipe2.me:8080 \
34
+ --server http://test.pipe2.me \
35
35
  --token review@pipe2me --ports 9090,9091</b>
36
36
  pretty-ivory-horse.test.pipe2.me
37
37
 
@@ -44,31 +44,31 @@ PIPE2ME_URLS_1=https://pretty-ivory-horse.test.pipe2.me:10004
44
44
  &gt; <b>pipe2me start</b>
45
45
  </pre>
46
46
 
47
- See also the [example session](http://test.pipe2.me/example_session.html)
47
+ See also the [example session](http://test.pipe2.me/example_session.html)
48
48
  and the [man page](http://test.pipe2.me/pipe2me.1.html).
49
49
 
50
50
  ## Testing
51
51
 
52
- Tests are implemented using
53
- [roundup](https://github.com/bmizerany/roundup/blob/master/INSTALLING#files).
54
- To install roundup on OSX, run `brew install roundup`. Other systems are
55
- supported as well, compare roundup's documentation for details.
52
+ Tests are implemented using roundup.
53
+ To install roundup on OSX, run `brew install roundup`. Other systems are
54
+ supported as well, [compare roundup's documentation](https://github.com/bmizerany/roundup/blob/master/INSTALLING#files)
55
+ for details.
56
56
 
57
- The implemented tests are *integration tests* in the sense, that they test the
58
- behaviour of the *pipe2me-client* package in connection to an external pipe2me
59
- server. That means you should run a pipe2me server on your local machine. Note
57
+ The implemented tests are *integration tests* in the sense, that they test the
58
+ behaviour of the *pipe2me-client* package in connection to an external pipe2me
59
+ server. That means you should run a pipe2me server on your local machine. Note
60
60
  that the server must be configured to support test mode. (In test mode a pipe2me
61
- server accepts test auth tokens, that create short lived tunnels
62
- with self-signed certificates.)
61
+ server accepts test auth tokens, that create short lived tunnels
62
+ with self-signed certificates.)
63
63
 
64
64
  To run the tests against a locally installed test server run `rake`. Note that
65
65
  the local test server is expected at "pipe2.dev:8080". You might have to adjust
66
- the `/etc/hosts` file to add an entry
66
+ the `/etc/hosts` file to add an entry
67
67
 
68
68
  127.0.0.1 pipe2.dev
69
69
 
70
- Before submitting a pull request you should also run a test against the
71
- test.pipe2.me instance, which is available most of the time for that purpose.
70
+ Before submitting a pull request you should also run a test against the
71
+ test.pipe2.me instance, which is available most of the time for that purpose.
72
72
  To do that, run `rake test:release`.
73
73
 
74
74
  ## Tunnel tokens
@@ -76,9 +76,9 @@ To do that, run `rake test:release`.
76
76
  As ports and domain names are sparse resources the pipe2me server API
77
77
  requires the use of authorization tokens when requesting a tunnel. A
78
78
  token is similar to a 'currency' in that it describes which tunnels are
79
- supported. A token could limit the number of ports that can be tunnelled,
80
- the amount of traffic for those ports, whether or not a certificate is
81
- self-signed or signed by a regular CA, etc.
79
+ supported. A token could limit the number of ports that can be tunnelled,
80
+ the amount of traffic for those ports, whether or not a certificate is
81
+ self-signed or signed by a regular CA, etc.
82
82
 
83
83
 
84
84
  The features of a token are not defined within this protocol. However,
@@ -87,24 +87,24 @@ to know more.
87
87
 
88
88
  A freshly installed pipe2me server comes with a number of preconfigured tokens.
89
89
  Of course, a server admin should (and probably would) change those tokens.
90
- However, as a test target, the pipe2me test server at http://test.pipe2.me:8080
91
- supports these tokens:
90
+ However, as a test target, the pipe2me test server at http://test.pipe2.me
91
+ supports these tokens:
92
92
 
93
93
  - `test@pipe2me`: this builds tunnels that are available for 5 minutes.
94
94
  The test token is intended for use with automated test scenarios.
95
- - `review@pipe2me`: this builds tunnels that are available for up to
95
+ - `review@pipe2me`: this builds tunnels that are available for up to
96
96
  one day. A review token should help you get a feel for the pipe2me
97
- package.
97
+ package.
98
98
 
99
- If you need a longer lived token for development, review and/or test
100
- feel free to contact us at contact@kinko.me.
99
+ If you need a longer lived token for development, review and/or test
100
+ feel free to contact us at contact@kinko.me.
101
101
 
102
102
  ## Licensing
103
103
 
104
- **The pipe2me client software** is (c) The Kinko Team, 2014 and released to you
104
+ **The pipe2me client software** is (c) The Kinko Team, 2014 and released to you
105
105
  under the terms of the MIT License (MIT), see COPYING.MIT for details.
106
106
 
107
107
  The subdirectory lib/vendor contains third-party code, which is subject to its own copyrights.
108
108
  Please see the respective source files for copyright information.
109
-
109
+
110
110
  (c) The kinko team, 2014
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env jit cc -g -Werror -Wall -lnatpmp --
2
+
3
+ /* $Id: natpmpc.c,v 1.13 2012/08/21 17:23:38 nanard Exp $ */
4
+ /* libnatpmp
5
+ Copyright (c) 2007-2011, Thomas BERNARD
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ * Redistributions of source code must retain the above copyright notice,
12
+ this list of conditions and the following disclaimer.
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+ * The name of the author may not be used to endorse or promote products
17
+ derived from this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+ #include <stdio.h>
32
+ #include <stdlib.h>
33
+ #include <errno.h>
34
+ #include <string.h>
35
+ #if defined(_MSC_VER)
36
+ #if _MSC_VER >= 1400
37
+ #define strcasecmp _stricmp
38
+ #else
39
+ #define strcasecmp stricmp
40
+ #endif
41
+ #else
42
+ #include <unistd.h>
43
+ #endif
44
+ #ifdef WIN32
45
+ #include <winsock2.h>
46
+ #else
47
+ #include <netinet/in.h>
48
+ #include <arpa/inet.h>
49
+ #endif
50
+
51
+ // #define ENABLE_STRNATPMPERR
52
+
53
+ #include "natpmp.h"
54
+
55
+ static const char * argv0;
56
+ static FILE* debug;
57
+
58
+ static void usage()
59
+ {
60
+ fprintf(stderr, "Usage :\n");
61
+ fprintf(stderr, " %s [options]\n", argv0);
62
+ fprintf(stderr, "\tdisplay the public IP address.\n");
63
+ fprintf(stderr, " %s [options] [protcol:]<public port>[:<private port>] <public port>[:<private port>] ... \n", argv0);
64
+ fprintf(stderr, "\tadd map one or more ports. protocol is 'tcp' or 'udp'.\n");
65
+ fprintf(stderr, "\nOption available :\n");
66
+ fprintf(stderr, " -g ipv4address\n\tforce the gateway to be used as destination for NAT-PMP commands.\n");
67
+ fprintf(stderr, " -l lifetime\n\tset lifetime for port mapping.\n");
68
+ fprintf(stderr, " -v\n\tbe verbose.\n");
69
+ fprintf(stderr, "\n In order to remove a mapping, set it with a lifetime of 0 seconds.\n");
70
+ fprintf(stderr, " To remove all mappings for your machine, use 0 as private port and lifetime.\n");
71
+
72
+ exit(1);
73
+ }
74
+
75
+ #define NO 0
76
+ #define YES 1
77
+
78
+ typedef struct {
79
+ int protocol;
80
+ uint16_t privateport;
81
+ uint16_t publicport;
82
+ uint32_t lifetime;
83
+ } port_mapping_t;
84
+
85
+ #define MAX_PORT_MAPPINGS 32
86
+
87
+ typedef struct {
88
+ int verbose;
89
+ int gateway;
90
+ port_mapping_t port_mappings[MAX_PORT_MAPPINGS];
91
+ unsigned port_mappings_count;
92
+ } arguments_t;
93
+
94
+ /*
95
+ * == Argument parsing ========================================================
96
+ */
97
+
98
+ static void parse_port_mapping(const char* s, port_mapping_t* p_port_mapping) {
99
+ p_port_mapping->publicport = 0;
100
+ p_port_mapping->privateport = 0;
101
+ p_port_mapping->protocol = NATPMP_PROTOCOL_TCP;
102
+
103
+ if(0 == strncasecmp(s, "tcp:", 4)) {
104
+ s += 4;
105
+ }
106
+ else if(0 == strncasecmp(s, "udp:", 4)) {
107
+ p_port_mapping->protocol = NATPMP_PROTOCOL_UDP;
108
+ s += 4;
109
+ }
110
+
111
+ if(2 == sscanf(s, "%hu:%hu", &p_port_mapping->publicport, &p_port_mapping->privateport)) {
112
+ return;
113
+ }
114
+
115
+ if(1 == sscanf(s, "%hu", &p_port_mapping->publicport)) {
116
+ p_port_mapping->privateport = p_port_mapping->publicport;
117
+ return;
118
+ }
119
+
120
+ fprintf(stderr, "Cannot parse port mapping '%s'\n", s);
121
+ exit(1);
122
+ }
123
+
124
+ static void parse_args(const char** argv, arguments_t* args) {
125
+ in_addr_t lifetime = 3600;
126
+
127
+ args->verbose = NO;
128
+ args->gateway = 0;
129
+ args->port_mappings_count = 0;
130
+
131
+ /* argument parsing */
132
+ while(*++argv) {
133
+ if(*argv[0] == '-') {
134
+ switch((*argv)[1]) {
135
+ case 'g':
136
+ if(!*++argv) usage();
137
+ args->gateway = inet_addr(*argv);
138
+ break;
139
+ case 'l':
140
+ if(!*++argv) usage();
141
+ lifetime = (unsigned)strtoul(*argv, (char **)NULL, 10);
142
+ break;
143
+ case 'v':
144
+ args->verbose = YES;
145
+ break;
146
+ default:
147
+ usage();
148
+ };
149
+ continue;
150
+ }
151
+
152
+ if(args->port_mappings_count == MAX_PORT_MAPPINGS) {
153
+ fprintf(stderr, "Cannot map more than %d ports at once.\n", MAX_PORT_MAPPINGS);
154
+ exit(1);
155
+ }
156
+
157
+ port_mapping_t* port_mapping = args->port_mappings + args->port_mappings_count;
158
+ parse_port_mapping(*argv, port_mapping);
159
+ port_mapping->lifetime = lifetime;
160
+ args->port_mappings_count++;
161
+ }
162
+ }
163
+
164
+ #define MAX_TRIES 6
165
+
166
+ /*
167
+ * == NAT-PMP high level interface ============================================
168
+ */
169
+
170
+ static int natpmp_init(natpmp_t* natpmp, arguments_t* args)
171
+ {
172
+ int r = initnatpmp(natpmp, args->gateway != 0, args->gateway);
173
+ fprintf(debug, "initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS");
174
+ if(r < 0) return NO;
175
+
176
+ /* log gateway */
177
+ struct in_addr gateway_in_use;
178
+ gateway_in_use.s_addr = natpmp->gateway;
179
+ fprintf(debug, "using NAT-PMP gateway : %s\n", inet_ntoa(gateway_in_use));
180
+
181
+ return YES;
182
+ }
183
+
184
+ static void natpmp_close(natpmp_t* natpmp)
185
+ {
186
+ int r = closenatpmp(natpmp);
187
+ fprintf(debug, "closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED");
188
+ }
189
+
190
+ static natpmpresp_t* natpmp_wait_for_success_response(natpmp_t* natpmp, natpmpresp_t* response) {
191
+ int remaining_tries = MAX_TRIES;
192
+
193
+ while(remaining_tries > 0) {
194
+ fd_set fds;
195
+ struct timeval timeout;
196
+
197
+ FD_ZERO(&fds);
198
+ FD_SET(natpmp->s, &fds);
199
+ getnatpmprequesttimeout(natpmp, &timeout);
200
+
201
+ if(0 > select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) {
202
+ perror("select()");
203
+ return 0;
204
+ }
205
+
206
+ int r = readnatpmpresponseorretry(natpmp, response);
207
+ int sav_errno = errno;
208
+ fprintf(debug, "readnatpmpresponseorretry returned %d (%s)\n", r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
209
+ if(r == 0) {
210
+ fprintf(debug, "epoch = %u\n", response->epoch);
211
+ return response;
212
+ }
213
+
214
+ if(r != NATPMP_TRYAGAIN) {
215
+ #ifdef ENABLE_STRNATPMPERR
216
+ fprintf(debug, "readnatpmpresponseorretry() failed : %s\n", strnatpmperr(r));
217
+ #endif
218
+ fprintf(debug, " errno=%d '%s'\n", sav_errno, strerror(sav_errno));
219
+ return 0;
220
+ }
221
+ }
222
+
223
+ fprintf(stderr, "Giving up after %d tries.\n", MAX_TRIES);
224
+ return 0;
225
+ }
226
+
227
+ static const char* natpmp_public_address(natpmp_t* natpmp, char* publicaddress)
228
+ {
229
+ int r = sendpublicaddressrequest(natpmp);
230
+ fprintf(debug, "sendpublicaddressrequest returned %d (%s)\n", r, r==2?"SUCCESS":"FAILED");
231
+ if(r<0) return 0;
232
+
233
+ natpmpresp_t response_buf;
234
+ natpmpresp_t *response = natpmp_wait_for_success_response(natpmp, &response_buf);
235
+ if(!response)
236
+ return 0;
237
+
238
+ /* TODO : check that response.type == 0 */
239
+ fprintf(debug, "Public IP address : %s\n", inet_ntoa(response->pnu.publicaddress.addr));
240
+ sprintf(publicaddress, "%s", inet_ntoa(response->pnu.publicaddress.addr));
241
+
242
+ return publicaddress;
243
+ }
244
+
245
+ static int natpmp_map_port(natpmp_t* natpmp, port_mapping_t* port_mapping, unsigned* lifetime) {
246
+ int r = sendnewportmappingrequest(natpmp, port_mapping->protocol,
247
+ port_mapping->privateport, port_mapping->publicport,
248
+ port_mapping->lifetime);
249
+ fprintf(debug, "sendnewportmappingrequest returned %d (%s)\n",
250
+ r, r==12?"SUCCESS":"FAILED");
251
+ if(r < 0)
252
+ return NO;
253
+
254
+ natpmpresp_t response_buf;
255
+ natpmpresp_t *response = natpmp_wait_for_success_response(natpmp, &response_buf);
256
+ if(!response) return NO;
257
+
258
+ *lifetime = response->pnu.newportmapping.lifetime;
259
+ return YES;
260
+ }
261
+
262
+ /*
263
+ * == main ====================================================================
264
+ */
265
+
266
+ int main(int argc, const char ** argv)
267
+ {
268
+
269
+ #ifdef WIN32
270
+ WSADATA wsaData;
271
+ int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
272
+ if(nResult != NO_ERROR)
273
+ {
274
+ fprintf(stderr, "WSAStartup() failed.\n");
275
+ return -1;
276
+ }
277
+ #endif
278
+
279
+ argv0 = argv[0];
280
+ arguments_t args;
281
+
282
+ parse_args(argv, &args);
283
+
284
+ debug = args.verbose ? stderr : fopen("/dev/null", "w");
285
+
286
+ // if(args.verbose) {
287
+ // unsigned i = 0;
288
+ // for(i = 0; i<args.port_mappings_count; ++i) {
289
+ // port_mapping_t* mapping = args.port_mappings + i;
290
+ //
291
+ // const char* protocol = mapping->protocol == NATPMP_PROTOCOL_UDP ? "udp" : "tcp";
292
+ // fprintf(stderr, "%s: public:%hu -> localhost:%hu: pending (lifetime %u)\n",
293
+ // protocol, mapping->publicport, mapping->privateport, mapping->lifetime);
294
+ // }
295
+ // }
296
+
297
+ /*
298
+ * Try to get NAT-PMP public IP. We use that to decide whether we are
299
+ * going NAT-PMP or UPnP.
300
+ */
301
+
302
+ natpmp_t natpmp;
303
+
304
+ if(!natpmp_init(&natpmp, &args)) {
305
+ fprintf(stderr, "Cannot initialize NAT-PMP.\n");
306
+ return 1;
307
+ }
308
+
309
+ char publicaddress_buf[32];
310
+ const char* publicaddress = natpmp_public_address(&natpmp, publicaddress_buf);
311
+ if(!publicaddress) {
312
+ fprintf(stderr, "NAT-PMP: Cannot find public IP address. NAT-PMP is not available.\n");
313
+ }
314
+
315
+ if(publicaddress) {
316
+ if(args.port_mappings_count == 0)
317
+ printf("%s\n", publicaddress);
318
+
319
+ unsigned i = 0;
320
+ for(i = 0; i<args.port_mappings_count; ++i) {
321
+ port_mapping_t* mapping = args.port_mappings + i;
322
+
323
+ unsigned lifetime = 0;
324
+ int r = natpmp_map_port(&natpmp, mapping, &lifetime);
325
+
326
+ const char* protocol = mapping->protocol == NATPMP_PROTOCOL_UDP ? "udp" : "tcp";
327
+ fprintf(stderr, "NAT-PMP: %s: %s:%hu -> localhost:%hu: %s (lifetime %u)\n",
328
+ protocol, publicaddress, mapping->publicport, mapping->privateport, (r ? "OK" : "FAIL"), lifetime);
329
+
330
+ if(!r) break;
331
+ }
332
+ }
333
+
334
+ natpmp_close(&natpmp);
335
+ return 0;
336
+ }
337
+
@@ -3,16 +3,20 @@ class Pipe2me::CLI < Thor
3
3
  option :echo, :type => :boolean, :banner => "Also run echo servers"
4
4
  def start
5
5
  handle_global_options
6
-
6
+
7
7
  procfile = options[:echo] ? "pipe2me.procfile.echo" : "pipe2me.procfile"
8
8
 
9
9
  File.open procfile, "w" do |io|
10
10
  Pipe2me::Tunnel.tunnel_commands.each do |name, cmd|
11
11
  io.write "#{name}: #{cmd}\n"
12
12
  end
13
-
13
+
14
+ # Pipe2me::Tunnel.mapping_commands.each do |name, cmd|
15
+ # io.write "#{name}: #{cmd}\n"
16
+ # end
17
+
14
18
  next unless options[:echo]
15
-
19
+
16
20
  Pipe2me::Tunnel.echo_commands.each do |name, cmd|
17
21
  io.write "#{name}: #{cmd}\n"
18
22
  end
@@ -4,32 +4,37 @@ class Pipe2me::CLI < Thor
4
4
  option :echo, :type => :boolean, :banner => "Also run echo servers"
5
5
  def monit(*args)
6
6
  handle_global_options
7
-
7
+
8
8
  monitrc_file = create_monitrc
9
-
9
+
10
10
  UI.warn "Running: monit -c #{monitrc_file} #{args.join(" ")}"
11
11
  Kernel.exec "monit", "-c", monitrc_file, *args
12
12
  end
13
-
13
+
14
14
  desc "monitrc", "Create monitrc file"
15
15
  option :port, :default => 5555, :banner => "control port"
16
16
  option :echo, :type => :boolean, :banner => "Also run echo servers"
17
17
  def monitrc
18
18
  handle_global_options
19
-
19
+
20
20
  monitrc_file = create_monitrc
21
21
  Kernel.exec "monit", "-c", monitrc_file, "-t"
22
22
  end
23
23
 
24
24
  private
25
-
25
+
26
+ def which!(cmd)
27
+ path = `which #{cmd}`.chomp
28
+ raise "Cannot find #{cmd} in your $PATH. Is it installed?" if path == ""
29
+ path
30
+ end
31
+
26
32
  def create_monitrc
27
33
  path = options[:echo] ? "pipe2me.monitrc.echo" : "pipe2me.monitrc"
28
34
 
29
35
  # The daemon binary
30
- daemon_bin = `which daemon`.chomp
31
- daemon = "#{daemon_bin} -D #{File.expand_path(Dir.getwd)}"
32
-
36
+ daemon = "#{which! :daemon} -D #{File.expand_path(Dir.getwd)}"
37
+
33
38
  port = options[:port]
34
39
 
35
40
  logfile = File.expand_path "pipe2me.monit.log"
@@ -37,22 +42,23 @@ class Pipe2me::CLI < Thor
37
42
  FileUtils.mkdir_p piddir
38
43
 
39
44
  commands = Pipe2me::Tunnel.tunnel_commands
45
+ # commands += Pipe2me::Tunnel.mapping_commands
40
46
  commands += Pipe2me::Tunnel.echo_commands if options[:echo]
41
-
47
+
42
48
  File.open path, "w", 0600 do |io|
43
49
  require "erb"
44
50
 
45
51
  erb = ERB.new MONITRC_ERB
46
52
  io.write erb.result(self.send(:binding))
47
53
  end
48
-
54
+
49
55
  UI.success "Created #{path}"
50
-
56
+
51
57
  path
52
58
  end
53
59
 
54
60
  MONITRC_ERB = %q{
55
- set daemon 10
61
+ set daemon 10
56
62
  set httpd port <%= port %> and use address localhost allow localhost
57
63
 
58
64
  <% commands.each do |name, cmd| %>
data/lib/pipe2me/cli.rb CHANGED
@@ -2,12 +2,12 @@ require "thor"
2
2
 
3
3
  class Pipe2me::CLI < Thor
4
4
  class_option :dir, :type => :string
5
- class_option :verbose, :type => :boolean, :aliases => :v
6
- class_option :quiet, :type => :boolean, :aliases => :q
5
+ class_option :verbose, :type => :boolean, :aliases => "-v"
6
+ class_option :quiet, :type => :boolean, :aliases => "-q"
7
7
  class_option :silent, :type => :boolean
8
-
8
+
9
9
  private
10
-
10
+
11
11
  def handle_global_options
12
12
  UI.verbosity = 2
13
13
  if options[:verbose]
@@ -25,24 +25,24 @@ class Pipe2me::CLI < Thor
25
25
  end
26
26
 
27
27
  public
28
-
28
+
29
29
  def self.exit_on_failure?; true; end
30
-
30
+
31
31
  desc "version", "print version information"
32
32
  def version
33
33
  handle_global_options
34
-
34
+
35
35
  puts Pipe2me::VERSION
36
36
  end
37
37
 
38
38
  desc "setup", "fetch a new tunnel setup"
39
- option :server, :aliases => :s, :default => "http://test.pipe2.me:8080"
39
+ option :server, :aliases => "-s", :default => "http://test.pipe2.me"
40
40
  option :token, :required => true # "tunnel token"
41
41
  option :protocols, :default => "https" # "protocol names, e.g. 'http,https,imap'"
42
42
  option :ports, :type => :string # "local ports, one per protocol"
43
43
  def setup
44
44
  handle_global_options
45
-
45
+
46
46
  Pipe2me::Config.server = options[:server]
47
47
  server_info = Pipe2me::Tunnel.setup options
48
48
 
@@ -53,7 +53,7 @@ class Pipe2me::CLI < Thor
53
53
  desc "env", "show tunnel configuration"
54
54
  def env(*args)
55
55
  handle_global_options
56
-
56
+
57
57
  puts File.read("pipe2me.local.inc")
58
58
  puts File.read("pipe2me.info.inc")
59
59
  end
@@ -61,21 +61,21 @@ class Pipe2me::CLI < Thor
61
61
  desc "verify", "Verify the tunnel"
62
62
  def verify
63
63
  handle_global_options
64
-
64
+
65
65
  Pipe2me::Tunnel.verify
66
66
  end
67
67
 
68
68
  desc "update", "Updates configuration"
69
69
  def update
70
70
  handle_global_options
71
-
71
+
72
72
  Pipe2me::Tunnel.update
73
73
  end
74
-
74
+
75
75
  desc "check", "check online status"
76
76
  def check
77
77
  handle_global_options
78
-
78
+
79
79
  Pipe2me::Tunnel.check
80
80
  end
81
81
  end
@@ -2,6 +2,6 @@ require "tmpdir"
2
2
 
3
3
  module Pipe2me::Config
4
4
  extend self
5
-
5
+
6
6
  attr :server, true
7
7
  end
@@ -21,10 +21,10 @@ module Pipe2me::HTTP
21
21
  end
22
22
 
23
23
  extend Forwardable
24
- delegate [ :code, :url ] => :@response
24
+ delegate [ :code, :url ] => :@response
25
25
 
26
26
  def message #:nodoc:
27
- "#{url}: #{code} #{@response[0..120]} (#{@response.response.class})"
27
+ "#{url}: #{code} #{@response[0..120]} (#{@response.response.class})"
28
28
  end
29
29
  end
30
30
 
@@ -2,14 +2,14 @@ require "shellwords"
2
2
 
3
3
  module Pipe2me::Sys
4
4
  extend self
5
-
5
+
6
6
  class ExitError < RuntimeError; end
7
-
7
+
8
8
  def sys(*args)
9
9
  cmd, stdout = _sys(*args)
10
10
  return stdout if $?.exitstatus == 0
11
11
  end
12
-
12
+
13
13
  def sys!(*args)
14
14
  cmd, stdout = _sys(*args)
15
15
  return stdout if $?.exitstatus == 0
@@ -19,18 +19,18 @@ module Pipe2me::Sys
19
19
  def sh(*args)
20
20
  sys "sh", "-c", *args
21
21
  end
22
-
22
+
23
23
  def sh!(*args)
24
24
  sys! "sh", "-c", *args
25
25
  end
26
-
26
+
27
27
  private
28
-
28
+
29
29
  def _sys(*args)
30
30
  cmd = args.
31
31
  map { |arg| Shellwords.escape arg.to_s }.
32
32
  join(" ")
33
-
33
+
34
34
  UI.debug cmd
35
35
  stdout = IO.popen(cmd, &:read)
36
36
  [ cmd, stdout ]
@@ -7,7 +7,7 @@ module Pipe2me::Tunnel::Commands
7
7
  def tunnels
8
8
  @tunnels ||= begin
9
9
  urls, ports = config.urls, config.ports.to_s.split(",")
10
-
10
+
11
11
  urls.zip(ports).map do |url, local_port|
12
12
  uri = URI.parse(url)
13
13
  [ uri.scheme, uri.port, local_port || uri.port ]
@@ -16,17 +16,25 @@ module Pipe2me::Tunnel::Commands
16
16
  end
17
17
 
18
18
  public
19
-
19
+
20
20
  # return an arry [ [name, command ], [name, command ], .. ]
21
21
  def tunnel_commands
22
22
  tunnel_uri = URI.parse config.tunnel
23
-
23
+
24
24
  tunnels.map do |protocol, remote_port, local_port|
25
25
  next unless cmd = port_tunnel_command(tunnel_uri, protocol, remote_port, local_port)
26
26
  [ "#{protocol}_#{remote_port}", cmd ]
27
27
  end.compact
28
28
  end
29
-
29
+
30
+ # def mapping_commands
31
+ # natpmpc = File.expand_path "#{File.dirname(__FILE__)}/../bin/natpmpc"
32
+ # mappings = tunnels.map do |_, remote_port, local_port|
33
+ # "tcp:#{remote_port}:#{local_port}"
34
+ # end
35
+ # [ [ "natpmpc", "#{natpmpc} #{mappings.join(" ")} && sleep 10000" ] ]
36
+ # end
37
+
30
38
  def echo_commands
31
39
  tunnels.map do |protocol, remote_port, local_port|
32
40
  next unless cmd = echo_server_command(protocol, local_port)
@@ -41,10 +49,10 @@ module Pipe2me::Tunnel::Commands
41
49
  raise "Cannot find #{cmd} in your $PATH. Is it installed?" if path == ""
42
50
  path
43
51
  end
44
-
52
+
45
53
  def port_tunnel_command(tunnel_uri, protocol, remote_port, local_port)
46
54
  autossh = which! :autossh
47
-
55
+
48
56
  cmd = <<-SHELL
49
57
  env AUTOSSH_GATETIME=0 # comments work here..
50
58
  #{autossh}
@@ -55,12 +63,13 @@ module Pipe2me::Tunnel::Commands
55
63
  -i #{T::SSH_PRIVKEY}
56
64
  -o StrictHostKeyChecking=no
57
65
  -o UserKnownHostsFile=pipe2me.known_hosts
66
+ -o PasswordAuthentication=no
58
67
  -N
59
68
  SHELL
60
-
69
+
61
70
  # remove comments and newlines from commands
62
71
  cmd.gsub(/( *#.*|\s+)/, " ").gsub(/(^ )|( $)/, "")
63
- end
72
+ end
64
73
 
65
74
  def echo_server_command(protocol, port)
66
75
  binary = File.dirname(__FILE__) + "/echo/#{protocol}"
@@ -44,7 +44,7 @@ require "webrick/https"
44
44
 
45
45
  RACK_SERVER_OPTIONS = {
46
46
  :app => Application,
47
- :BindAddress => "localhost",
47
+ # :BindAddress => "localhost",
48
48
  :Port => ENV["PORT"] || 8080,
49
49
  :server => "webrick",
50
50
  :Logger => WEBrick::BasicLog.new($stderr, WEBrick::BasicLog::WARN)
@@ -73,7 +73,7 @@ module Pipe2me::Tunnel
73
73
  r = HTTP.get! "#{url}/check"
74
74
  puts r
75
75
  end
76
-
76
+
77
77
  def update
78
78
  unless File.exists?(SSH_PRIVKEY)
79
79
  ssh_keygen
@@ -1,4 +1,4 @@
1
1
  module Pipe2me
2
- VERSION = "0.2.8"
3
- BANNER = "pipe2me command line client V#{Pipe2me::VERSION}; (c) The kink team, 2013, 2014."
2
+ VERSION = "0.2.9"
3
+ BANNER = "pipe2me command line client V#{Pipe2me::VERSION}; (c) The kinko team, 2013, 2014."
4
4
  end
data/test/env-test.sh CHANGED
@@ -9,7 +9,7 @@ it_start_a_tunnel() {
9
9
  echo "== env is ============="
10
10
  cat env
11
11
  echo "== env done ============="
12
-
12
+
13
13
  cat env | grep PIPE2ME_SERVER
14
14
  cat env | grep PIPE2ME_ID
15
15
  cat env | grep PIPE2ME_FQDN
data/test/monitrc-test.sh CHANGED
@@ -17,7 +17,7 @@ it_creates_a_monitrc_file() {
17
17
 
18
18
  $pipe2me monitrc
19
19
  [ -e pipe2me.monitrc ]
20
-
20
+
21
21
  # The file is 0600
22
22
  ls -l pipe2me.monitrc | grep -e "-rw-------"
23
23
  }
@@ -7,7 +7,7 @@ describe "openssl tests"
7
7
  it_sets_up_openssl_certs() {
8
8
  fqdn=$($pipe2me setup --server $pipe2me_server --token $pipe2me_token)
9
9
  test -f pipe2me.openssl.priv
10
- cat pipe2me.openssl.priv | grep "BEGIN RSA PRIVATE KEY"
10
+ cat pipe2me.openssl.priv | grep -E "BEGIN.*PRIVATE KEY"
11
11
 
12
12
  test -f pipe2me.openssl.cert
13
13
  cat pipe2me.openssl.cert | grep "BEGIN CERTIFICATE"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env roundup
2
- describe 'a HTTP(s) connection to subdomain.$pipe2me_server redirects to subdomain.$pipe2me_server:port'
2
+ describe 'a HTTP(s) connection to subdomain.$pipe2me_server redirects to subdomain.$pipe2me_server:port'
3
3
 
4
4
  . $(dirname $1)/testhelper.inc
5
5
 
data/test/setup-test.sh CHANGED
@@ -6,12 +6,14 @@ describe "tunnel setup"
6
6
  # setup a tunnel
7
7
  it_sets_up_tunnels() {
8
8
  fqdn=$($pipe2me setup --server $pipe2me_server --token $pipe2me_token --ports 8100,8101 --protocols http,https)
9
-
9
+
10
+ test "$fqdn" != ""
11
+
10
12
  # pipe2me setup --server $pipe2me_server returns the fqdn of the subdomain and nothing else
11
- test 1 -eq $(echo $fqdn | wc -l)
13
+ test 1 -eq $(echo $fqdn | wc -l)
12
14
 
13
15
  # The subdomain is actually a subdomain.
14
- echo $fqdn | grep \.pipe2\.dev
16
+ echo $fqdn | grep \.pipe2\.
15
17
 
16
18
  # Cannot setup a second tunnel in the same directory.
17
19
  ! $pipe2me setup --server $pipe2me_server --token $pipe2me_token
data/test/sshkey-test.sh CHANGED
@@ -7,7 +7,7 @@ it_sets_up_ssh_identity() {
7
7
  fqdn=$($pipe2me setup --server $pipe2me_server --token $pipe2me_token)
8
8
  test -f pipe2me.id_rsa.pub
9
9
  test -f pipe2me.id_rsa
10
-
10
+
11
11
  # identity must contain $fqdn
12
12
  cat pipe2me.id_rsa.pub | grep $fqdn
13
13
  }
data/test/testhelper.inc CHANGED
@@ -1,6 +1,6 @@
1
1
  # The pipe2me binary to test
2
2
  pipe2me=$(cd $(dirname $1)/../bin && pwd)/pipe2me
3
- # pipe2me_server=http://test.pipe2.me:8080
3
+ # pipe2me_server=http://test.pipe2.me
4
4
 
5
5
  # Load test scenario settings
6
6
  echo "Load $TEST_ENV test settings"
@@ -1,2 +1,2 @@
1
- pipe2me_server=http://pipe2.dev:8080
1
+ pipe2me_server=http://test.pipe2.me
2
2
  pipe2me_token=test@pipe2me
data/test/verify-test.sh CHANGED
@@ -8,11 +8,11 @@ it_sets_up_tunnels_and_verifies() {
8
8
  fqdn=$($pipe2me setup --server $pipe2me_server --token short@pipe2me)
9
9
 
10
10
  # pipe2me setup --server $pipe2me_server returns the fqdn of the subdomain and nothing else
11
- test 1 -eq $(echo $fqdn | wc -l)
11
+ test 1 -eq $(echo $fqdn | wc -l)
12
12
 
13
13
  verified=$($pipe2me verify)
14
- test "$fqdn" == "$verified"
15
-
14
+ test "$fqdn" = "$verified"
15
+
16
16
  # sleep 4 seconds. The tunnel lives for 3 seconds
17
17
  sleep 4
18
18
  ! $pipe2me verify
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipe2me-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - radiospiel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-23 00:00:00.000000000 Z
11
+ date: 2014-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: pipe2me command line client V0.2.8; (c) The kink team, 2013, 2014.
69
+ description: pipe2me command line client V0.2.9; (c) The kinko team, 2013, 2014.
70
70
  email: contact@kinko.me
71
71
  executables:
72
72
  - pipe2me
@@ -77,6 +77,7 @@ files:
77
77
  - bin/pipe2me
78
78
  - bin/pipe2med
79
79
  - lib/pipe2me.rb
80
+ - lib/pipe2me/bin/natpmpc
80
81
  - lib/pipe2me/cli-foreman.rb
81
82
  - lib/pipe2me/cli-monit.rb
82
83
  - lib/pipe2me/cli.rb
@@ -131,5 +132,5 @@ rubyforge_project:
131
132
  rubygems_version: 2.2.1
132
133
  signing_key:
133
134
  specification_version: 4
134
- summary: pipe2me command line client V0.2.8; (c) The kink team, 2013, 2014.
135
+ summary: pipe2me command line client V0.2.9; (c) The kinko team, 2013, 2014.
135
136
  test_files: []