~ubuntu-branches/ubuntu/quantal/libssh/quantal-updates

« back to all changes in this revision

Viewing changes to .pc/0002-socket-Fixed-uninitialized-fd-revents-member.patch/libssh/socket.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2010-12-11 01:33:45 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: james.westby@ubuntu.com-20101211013345-ikpz4abendlkpvn6
Tags: 0.4.5-3
d/p/0002-socket-Fixed-uninitialized-fd-revents-member.patch:
Fix uninitialized memory use (Closes: #606347)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * socket.c - socket functions for the library
 
3
 *
 
4
 * This file is part of the SSH Library
 
5
 *
 
6
 * Copyright (c) 2008      by Aris Adamantiadis
 
7
 *
 
8
 * The SSH Library is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU Lesser General Public License as published by
 
10
 * the Free Software Foundation; either version 2.1 of the License, or (at your
 
11
 * option) any later version.
 
12
 *
 
13
 * The SSH Library is distributed in the hope that it will be useful, but
 
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
16
 * License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public License
 
19
 * along with the SSH Library; see the file COPYING.  If not, write to
 
20
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
21
 * MA 02111-1307, USA.
 
22
 */
 
23
 
 
24
#include <errno.h>
 
25
#include <string.h>
 
26
#include <stdlib.h>
 
27
#include <stdio.h>
 
28
#ifdef _WIN32
 
29
#include <winsock2.h>
 
30
#include <ws2tcpip.h>
 
31
#else
 
32
#include <fcntl.h>
 
33
#include <sys/types.h>
 
34
#include <sys/socket.h>
 
35
#include <sys/un.h>
 
36
extern char **environ;
 
37
#endif
 
38
#include "libssh/priv.h"
 
39
#include "libssh/socket.h"
 
40
#include "libssh/buffer.h"
 
41
#include "libssh/poll.h"
 
42
#include "libssh/session.h"
 
43
 
 
44
 
 
45
/** \defgroup ssh_socket SSH Sockets
 
46
 * \addtogroup ssh_socket
 
47
 * @{
 
48
 */
 
49
 
 
50
struct socket {
 
51
  socket_t fd;
 
52
  int last_errno;
 
53
  int data_to_read; /* reading now on socket will
 
54
                       not block */
 
55
  int data_to_write;
 
56
  int data_except;
 
57
  ssh_buffer out_buffer;
 
58
  ssh_buffer in_buffer;
 
59
  ssh_session session;
 
60
};
 
61
 
 
62
/*
 
63
 * \internal
 
64
 * \brief inits the socket system (windows specific)
 
65
 */
 
66
int ssh_socket_init(void) {
 
67
#ifdef _WIN32
 
68
  struct WSAData wsaData;
 
69
 
 
70
  /* Initiates use of the Winsock DLL by a process. */
 
71
  if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
 
72
    return -1;
 
73
  }
 
74
 
 
75
#endif
 
76
  ssh_poll_init();
 
77
 
 
78
  return 0;
 
79
}
 
80
/*
 
81
 * \internal
 
82
 * \brief creates a new Socket object
 
83
 */
 
84
struct socket *ssh_socket_new(ssh_session session) {
 
85
  struct socket *s;
 
86
 
 
87
  s = malloc(sizeof(struct socket));
 
88
  if (s == NULL) {
 
89
    return NULL;
 
90
  }
 
91
  s->fd = SSH_INVALID_SOCKET;
 
92
  s->last_errno = -1;
 
93
  s->session = session;
 
94
  s->in_buffer = buffer_new();
 
95
  if (s->in_buffer == NULL) {
 
96
    SAFE_FREE(s);
 
97
    return NULL;
 
98
  }
 
99
  s->out_buffer=buffer_new();
 
100
  if (s->out_buffer == NULL) {
 
101
    buffer_free(s->in_buffer);
 
102
    SAFE_FREE(s);
 
103
    return NULL;
 
104
  }
 
105
  s->data_to_read = 0;
 
106
  s->data_to_write = 0;
 
107
  s->data_except = 0;
 
108
 
 
109
  return s;
 
110
}
 
111
 
 
112
/* \internal
 
113
 * \brief Deletes a socket object
 
114
 */
 
115
void ssh_socket_free(struct socket *s){
 
116
  if (s == NULL) {
 
117
    return;
 
118
  }
 
119
  ssh_socket_close(s);
 
120
  buffer_free(s->in_buffer);
 
121
  buffer_free(s->out_buffer);
 
122
  SAFE_FREE(s);
 
123
}
 
124
 
 
125
#ifndef _WIN32
 
126
int ssh_socket_unix(struct socket *s, const char *path) {
 
127
  struct sockaddr_un sunaddr;
 
128
 
 
129
  sunaddr.sun_family = AF_UNIX;
 
130
  snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path);
 
131
 
 
132
  s->fd = socket(AF_UNIX, SOCK_STREAM, 0);
 
133
  if (s->fd == SSH_INVALID_SOCKET) {
 
134
    return -1;
 
135
  }
 
136
 
 
137
  if (fcntl(s->fd, F_SETFD, 1) == -1) {
 
138
    close(s->fd);
 
139
    s->fd = SSH_INVALID_SOCKET;
 
140
    return -1;
 
141
  }
 
142
 
 
143
  if (connect(s->fd, (struct sockaddr *) &sunaddr,
 
144
        sizeof(sunaddr)) < 0) {
 
145
    close(s->fd);
 
146
    s->fd = SSH_INVALID_SOCKET;
 
147
    return -1;
 
148
  }
 
149
 
 
150
  return 0;
 
151
}
 
152
#endif
 
153
 
 
154
/* \internal
 
155
 * \brief closes a socket
 
156
 */
 
157
void ssh_socket_close(struct socket *s){
 
158
  if (ssh_socket_is_open(s)) {
 
159
#ifdef _WIN32
 
160
    closesocket(s->fd);
 
161
    s->last_errno = WSAGetLastError();
 
162
#else
 
163
    close(s->fd);
 
164
    s->last_errno = errno;
 
165
#endif
 
166
    s->fd = SSH_INVALID_SOCKET;
 
167
  }
 
168
}
 
169
 
 
170
/* \internal
 
171
 * \brief sets the file descriptor of the socket
 
172
 */
 
173
void ssh_socket_set_fd(struct socket *s, socket_t fd) {
 
174
  s->fd = fd;
 
175
}
 
176
 
 
177
/* \internal
 
178
 * \brief returns the file descriptor of the socket
 
179
 */
 
180
socket_t ssh_socket_get_fd(struct socket *s) {
 
181
  return s->fd;
 
182
}
 
183
 
 
184
/* \internal
 
185
 * \brief returns nonzero if the socket is open
 
186
 */
 
187
int ssh_socket_is_open(struct socket *s) {
 
188
  return s->fd != SSH_INVALID_SOCKET;
 
189
}
 
190
 
 
191
/* \internal
 
192
 * \brief read len bytes from socket into buffer
 
193
 */
 
194
static int ssh_socket_unbuffered_read(struct socket *s, void *buffer, uint32_t len) {
 
195
  int rc = -1;
 
196
 
 
197
  if (s->data_except) {
 
198
    return -1;
 
199
  }
 
200
 
 
201
  rc = recv(s->fd,buffer, len, 0);
 
202
#ifdef _WIN32
 
203
  s->last_errno = WSAGetLastError();
 
204
#else
 
205
  s->last_errno = errno;
 
206
#endif
 
207
  s->data_to_read = 0;
 
208
 
 
209
  if (rc < 0) {
 
210
    s->data_except = 1;
 
211
  }
 
212
 
 
213
  return rc;
 
214
}
 
215
 
 
216
/* \internal
 
217
 * \brief writes len bytes from buffer to socket
 
218
 */
 
219
static int ssh_socket_unbuffered_write(struct socket *s, const void *buffer,
 
220
    uint32_t len) {
 
221
  int w = -1;
 
222
 
 
223
  if (s->data_except) {
 
224
    return -1;
 
225
  }
 
226
 
 
227
  w = send(s->fd,buffer, len, 0);
 
228
#ifdef _WIN32
 
229
  s->last_errno = WSAGetLastError();
 
230
#else
 
231
  s->last_errno = errno;
 
232
#endif
 
233
  s->data_to_write = 0;
 
234
 
 
235
  if (w < 0) {
 
236
    s->data_except = 1;
 
237
  }
 
238
 
 
239
  return w;
 
240
}
 
241
 
 
242
/* \internal
 
243
 * \brief returns nonzero if the current socket is in the fd_set
 
244
 */
 
245
int ssh_socket_fd_isset(struct socket *s, fd_set *set) {
 
246
  if(s->fd == SSH_INVALID_SOCKET) {
 
247
    return 0;
 
248
  }
 
249
  return FD_ISSET(s->fd,set);
 
250
}
 
251
 
 
252
/* \internal
 
253
 * \brief sets the current fd in a fd_set and updates the max_fd
 
254
 */
 
255
 
 
256
void ssh_socket_fd_set(struct socket *s, fd_set *set, socket_t *max_fd) {
 
257
  if (s->fd == SSH_INVALID_SOCKET)
 
258
    return;
 
259
  FD_SET(s->fd,set);
 
260
 
 
261
  if (s->fd >= 0 &&
 
262
      s->fd >= *max_fd &&
 
263
      s->fd != SSH_INVALID_SOCKET) {
 
264
    *max_fd = s->fd + 1;
 
265
  }
 
266
}
 
267
 
 
268
/** \internal
 
269
 * \brief reads blocking until len bytes have been read
 
270
 */
 
271
int ssh_socket_completeread(struct socket *s, void *buffer, uint32_t len) {
 
272
  int r = -1;
 
273
  uint32_t total = 0;
 
274
  uint32_t toread = len;
 
275
  if(! ssh_socket_is_open(s)) {
 
276
    return SSH_ERROR;
 
277
  }
 
278
 
 
279
  while((r = ssh_socket_unbuffered_read(s, ((uint8_t*)buffer + total), toread))) {
 
280
    if (r < 0) {
 
281
      return SSH_ERROR;
 
282
    }
 
283
    total += r;
 
284
    toread -= r;
 
285
    if (total == len) {
 
286
      return len;
 
287
    }
 
288
    if (r == 0) {
 
289
      return 0;
 
290
    }
 
291
  }
 
292
 
 
293
  /* connection closed */
 
294
  return total;
 
295
}
 
296
 
 
297
/** \internal
 
298
 * \brief Blocking write of len bytes
 
299
 */
 
300
int ssh_socket_completewrite(struct socket *s, const void *buffer, uint32_t len) {
 
301
  ssh_session session = s->session;
 
302
  int written = -1;
 
303
 
 
304
  enter_function();
 
305
 
 
306
  if(! ssh_socket_is_open(s)) {
 
307
    leave_function();
 
308
    return SSH_ERROR;
 
309
  }
 
310
 
 
311
  while (len >0) {
 
312
    written = ssh_socket_unbuffered_write(s, buffer, len);
 
313
    if (written == 0 || written == -1) {
 
314
      leave_function();
 
315
      return SSH_ERROR;
 
316
    }
 
317
    len -= written;
 
318
    buffer = ((uint8_t*)buffer +  written);
 
319
  }
 
320
 
 
321
  leave_function();
 
322
  return SSH_OK;
 
323
}
 
324
 
 
325
/** \internal
 
326
 * \brief buffered read of data (complete)
 
327
 * \returns SSH_OK or SSH_ERROR.
 
328
 * \returns SSH_AGAIN in nonblocking mode
 
329
 */
 
330
int ssh_socket_read(struct socket *s, void *buffer, int len){
 
331
  ssh_session session = s->session;
 
332
  int rc = SSH_ERROR;
 
333
 
 
334
  enter_function();
 
335
 
 
336
  rc = ssh_socket_wait_for_data(s, s->session, len);
 
337
  if (rc != SSH_OK) {
 
338
    leave_function();
 
339
    return rc;
 
340
  }
 
341
 
 
342
  memcpy(buffer, buffer_get_rest(s->in_buffer), len);
 
343
  buffer_pass_bytes(s->in_buffer, len);
 
344
 
 
345
  leave_function();
 
346
  return SSH_OK;
 
347
}
 
348
 
 
349
#define WRITE_BUFFERING_THRESHOLD 65536
 
350
/** \internal
 
351
 * \brief buffered write of data
 
352
 * \returns SSH_OK, or SSH_ERROR
 
353
 * \warning has no effect on socket before a flush
 
354
 */
 
355
int ssh_socket_write(struct socket *s, const void *buffer, int len) {
 
356
  ssh_session session = s->session;
 
357
  int rc = SSH_ERROR;
 
358
 
 
359
  enter_function();
 
360
 
 
361
  if (buffer_add_data(s->out_buffer, buffer, len) < 0) {
 
362
    return SSH_ERROR;
 
363
  }
 
364
 
 
365
  if (buffer_get_rest_len(s->out_buffer) > WRITE_BUFFERING_THRESHOLD) {
 
366
    rc = ssh_socket_nonblocking_flush(s);
 
367
  } else {
 
368
    rc = len;
 
369
  }
 
370
 
 
371
  leave_function();
 
372
  return rc;
 
373
}
 
374
 
 
375
 
 
376
/** \internal
 
377
 * \brief wait for data on socket
 
378
 * \param s socket
 
379
 * \param session the ssh session
 
380
 * \param len number of bytes to be read
 
381
 * \returns SSH_OK bytes are available on socket
 
382
 * \returns SSH_AGAIN need to call later for data
 
383
 * \returns SSH_ERROR error happened
 
384
 */
 
385
int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len) {
 
386
  char buffer[4096] = {0};
 
387
  char *buf = NULL;
 
388
  int except;
 
389
  int can_write;
 
390
  int to_read;
 
391
  int r;
 
392
 
 
393
  enter_function();
 
394
 
 
395
  to_read = len - buffer_get_rest_len(s->in_buffer);
 
396
 
 
397
  if (to_read <= 0) {
 
398
    leave_function();
 
399
    return SSH_OK;
 
400
  }
 
401
 
 
402
  if (session->blocking) {
 
403
    buf = malloc(to_read);
 
404
    if (buf == NULL) {
 
405
      leave_function();
 
406
      return SSH_ERROR;
 
407
    }
 
408
 
 
409
    r = ssh_socket_completeread(session->socket,buf,to_read);
 
410
    if (r == SSH_ERROR || r == 0) {
 
411
      ssh_set_error(session, SSH_FATAL,
 
412
          (r == 0) ? "Connection closed by remote host" :
 
413
          "Error reading socket");
 
414
      ssh_socket_close(session->socket);
 
415
      session->alive = 0;
 
416
      SAFE_FREE(buf);
 
417
 
 
418
      leave_function();
 
419
      return SSH_ERROR;
 
420
    }
 
421
 
 
422
    if (buffer_add_data(s->in_buffer,buf,to_read) < 0) {
 
423
      SAFE_FREE(buf);
 
424
      leave_function();
 
425
      return SSH_ERROR;
 
426
    }
 
427
 
 
428
    SAFE_FREE(buf);
 
429
 
 
430
    leave_function();
 
431
    return SSH_OK;
 
432
  }
 
433
 
 
434
  /* nonblocking read */
 
435
  do {
 
436
    /* internally sets data_to_read */
 
437
    r = ssh_socket_poll(s, &can_write, &except);
 
438
    if (r < 0 || !s->data_to_read) {
 
439
      leave_function();
 
440
      return SSH_AGAIN;
 
441
    }
 
442
 
 
443
    /* read as much as we can */
 
444
    if (ssh_socket_is_open(session->socket)) {
 
445
      r = ssh_socket_unbuffered_read(session->socket, buffer, sizeof(buffer));
 
446
    } else {
 
447
      r = -1;
 
448
    }
 
449
 
 
450
    if (r <= 0) {
 
451
      ssh_set_error(session, SSH_FATAL,
 
452
          (r == 0) ? "Connection closed by remote host" :
 
453
          "Error reading socket");
 
454
      ssh_socket_close(session->socket);
 
455
      session->alive = 0;
 
456
 
 
457
      leave_function();
 
458
      return SSH_ERROR;
 
459
    }
 
460
 
 
461
    if (buffer_add_data(s->in_buffer,buffer, (uint32_t) r) < 0) {
 
462
      leave_function();
 
463
      return SSH_ERROR;
 
464
    }
 
465
  } while(buffer_get_rest_len(s->in_buffer) < len);
 
466
 
 
467
  leave_function();
 
468
  return SSH_OK;
 
469
}
 
470
 
 
471
/* ssh_socket_poll */
 
472
int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
 
473
  ssh_session session = s->session;
 
474
  ssh_pollfd_t fd[1];
 
475
  int rc = -1;
 
476
 
 
477
  enter_function();
 
478
 
 
479
  if (!ssh_socket_is_open(s)) {
 
480
    *except = 1;
 
481
    *writeable = 0;
 
482
    return 0;
 
483
  }
 
484
 
 
485
  fd->fd = s->fd;
 
486
  fd->events = 0;
 
487
 
 
488
  if (!s->data_to_read) {
 
489
    fd->events |= POLLIN;
 
490
  }
 
491
  if (!s->data_to_write) {
 
492
    fd->events |= POLLOUT;
 
493
  }
 
494
  /* do not do poll if fd->events is empty, we already know the response */
 
495
  if(fd->events != 0){
 
496
        /* Make the call, and listen for errors */
 
497
        rc = ssh_poll(fd, 1, 0);
 
498
        if (rc < 0) {
 
499
                ssh_set_error(session, SSH_FATAL, "poll(): %s", strerror(errno));
 
500
                leave_function();
 
501
                return -1;
 
502
        }
 
503
  }
 
504
 
 
505
  if (!s->data_to_read) {
 
506
    s->data_to_read = fd->revents & POLLIN;
 
507
  }
 
508
  if (!s->data_to_write) {
 
509
    s->data_to_write = fd->revents & POLLOUT;
 
510
  }
 
511
  if (!s->data_except) {
 
512
    s->data_except = fd->revents & POLLERR;
 
513
  }
 
514
 
 
515
  *except = s->data_except;
 
516
  *writeable = s->data_to_write;
 
517
 
 
518
  leave_function();
 
519
  return (s->data_to_read || (buffer_get_rest_len(s->in_buffer) > 0));
 
520
}
 
521
 
 
522
/** \internal
 
523
 * \brief nonblocking flush of the output buffer
 
524
 */
 
525
int ssh_socket_nonblocking_flush(struct socket *s) {
 
526
  ssh_session session = s->session;
 
527
  int except;
 
528
  int can_write;
 
529
  int w;
 
530
 
 
531
  enter_function();
 
532
 
 
533
  /* internally sets data_to_write */
 
534
  if (ssh_socket_poll(s, &can_write, &except) < 0) {
 
535
    leave_function();
 
536
    return SSH_ERROR;
 
537
  }
 
538
 
 
539
  if (!ssh_socket_is_open(s)) {
 
540
    session->alive = 0;
 
541
    /* FIXME use ssh_socket_get_errno */
 
542
    ssh_set_error(session, SSH_FATAL,
 
543
        "Writing packet: error on socket (or connection closed): %s",
 
544
        strerror(errno));
 
545
 
 
546
    leave_function();
 
547
    return SSH_ERROR;
 
548
  }
 
549
 
 
550
  while(s->data_to_write && buffer_get_rest_len(s->out_buffer) > 0) {
 
551
    if (ssh_socket_is_open(s)) {
 
552
      w = ssh_socket_unbuffered_write(s, buffer_get_rest(s->out_buffer),
 
553
          buffer_get_rest_len(s->out_buffer));
 
554
    } else {
 
555
      /* write failed */
 
556
      w = -1;
 
557
    }
 
558
 
 
559
    if (w < 0) {
 
560
      session->alive = 0;
 
561
      ssh_socket_close(s);
 
562
      /* FIXME use ssh_socket_get_errno() */
 
563
      ssh_set_error(session, SSH_FATAL,
 
564
          "Writing packet: error on socket (or connection closed): %s",
 
565
          strerror(errno));
 
566
 
 
567
      leave_function();
 
568
      return SSH_ERROR;
 
569
    }
 
570
 
 
571
    buffer_pass_bytes(s->out_buffer, w);
 
572
    /* refresh the socket status */
 
573
    if (ssh_socket_poll(session->socket, &can_write, &except) < 0) {
 
574
      leave_function();
 
575
      return SSH_ERROR;
 
576
    }
 
577
  }
 
578
 
 
579
  /* Is there some data pending? */
 
580
  if (buffer_get_rest_len(s->out_buffer) > 0) {
 
581
    leave_function();
 
582
    return SSH_AGAIN;
 
583
  }
 
584
 
 
585
  /* all data written */
 
586
  leave_function();
 
587
  return SSH_OK;
 
588
}
 
589
 
 
590
 
 
591
/** \internal
 
592
 * \brief locking flush of the output packet buffer
 
593
 */
 
594
int ssh_socket_blocking_flush(struct socket *s) {
 
595
  ssh_session session = s->session;
 
596
 
 
597
  enter_function();
 
598
 
 
599
  if (!ssh_socket_is_open(s)) {
 
600
    session->alive = 0;
 
601
 
 
602
    leave_function();
 
603
    return SSH_ERROR;
 
604
  }
 
605
 
 
606
  if (s->data_except) {
 
607
    leave_function();
 
608
    return SSH_ERROR;
 
609
  }
 
610
 
 
611
  if (buffer_get_rest_len(s->out_buffer) == 0) {
 
612
    leave_function();
 
613
    return SSH_OK;
 
614
  }
 
615
 
 
616
  if (ssh_socket_completewrite(s, buffer_get_rest(s->out_buffer),
 
617
        buffer_get_rest_len(s->out_buffer)) != SSH_OK) {
 
618
    session->alive = 0;
 
619
    ssh_socket_close(s);
 
620
    /* FIXME use the proper errno */
 
621
    ssh_set_error(session, SSH_FATAL,
 
622
        "Writing packet: error on socket (or connection closed): %s",
 
623
        strerror(errno));
 
624
 
 
625
    leave_function();
 
626
    return SSH_ERROR;
 
627
  }
 
628
 
 
629
  if (buffer_reinit(s->out_buffer) < 0) {
 
630
    leave_function();
 
631
    return SSH_ERROR;
 
632
  }
 
633
 
 
634
  leave_function();
 
635
  return SSH_OK; // no data pending
 
636
}
 
637
 
 
638
void ssh_socket_set_towrite(struct socket *s) {
 
639
  s->data_to_write = 1;
 
640
}
 
641
 
 
642
void ssh_socket_set_toread(struct socket *s) {
 
643
  s->data_to_read = 1;
 
644
}
 
645
 
 
646
void ssh_socket_set_except(struct socket *s) {
 
647
  s->data_except = 1;
 
648
}
 
649
 
 
650
int ssh_socket_data_available(struct socket *s) {
 
651
  return s->data_to_read;
 
652
}
 
653
 
 
654
int ssh_socket_data_writable(struct socket *s) {
 
655
  return s->data_to_write;
 
656
}
 
657
 
 
658
int ssh_socket_get_status(struct socket *s) {
 
659
  int r = 0;
 
660
 
 
661
  if (s->data_to_read) {
 
662
    r |= SSH_READ_PENDING;
 
663
  }
 
664
 
 
665
  if (s->data_except) {
 
666
    r |= SSH_CLOSED_ERROR;
 
667
  }
 
668
 
 
669
  return r;
 
670
}
 
671
 
 
672
#ifndef _WIN32
 
673
/**
 
674
 * @internal
 
675
 * @brief executes a command and redirect input and outputs
 
676
 * @param command command to execute
 
677
 * @param in input file descriptor
 
678
 * @param out output file descriptor
 
679
 */
 
680
void ssh_execute_command(const char *command, socket_t in, socket_t out){
 
681
  const char *args[]={"/bin/sh","-c",command,NULL};
 
682
  /* redirect in and out to stdin, stdout and stderr */
 
683
  dup2(in, 0);
 
684
  dup2(out,1);
 
685
  dup2(out,2);
 
686
  close(in);
 
687
  close(out);
 
688
  execve(args[0],(char * const *)args,(char * const *)environ);
 
689
  exit(1);
 
690
}
 
691
 
 
692
/**
 
693
 * @internal
 
694
 * @brief Open a socket on a ProxyCommand
 
695
 * This call will always be nonblocking.
 
696
 * @param s    socket to connect.
 
697
 * @param command Command to execute.
 
698
 * @returns SSH_OK socket is being connected.
 
699
 * @returns SSH_ERROR error while executing the command.
 
700
 */
 
701
 
 
702
socket_t ssh_socket_connect_proxycommand(ssh_session session,
 
703
    const char *command){
 
704
  socket_t fd[2];
 
705
  int pid;
 
706
  enter_function();
 
707
  socketpair(AF_UNIX,SOCK_STREAM,0,fd);
 
708
  pid = fork();
 
709
  if(pid == 0){
 
710
    ssh_execute_command(command,fd[1],fd[1]);
 
711
  }
 
712
  close(fd[1]);
 
713
  ssh_log(session,SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",fd[0],fd[1]);
 
714
  return fd[0];
 
715
}
 
716
 
 
717
#endif /* _WIN32 */
 
718
 
 
719
 
 
720
/** @}
 
721
 */
 
722
/* vim: set ts=2 sw=2 et cindent: */