pipe2me-client 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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: []