Exemplo n.º 1
0
char *ssh_str_extract(const char *source,
                      char **target,
                      char delimiter, int occurence)
{
  int c, len, i = 0;

  if (!source) return NULL;
  if (!target) return NULL;

  while (occurence > 0 && source[i] != '\0')
    if (source[i++] == delimiter) occurence--;

  /* Did we find a substring. If not return an empty string*/
  if (occurence != 0)
    {
      *target = ssh_xmalloc(1);
      (*target)[0] = '\0';
      return *target;
    }

  /* preserve our location in string */
  c = i;

  /* Count the length of asked substring */
  while (source[i] != delimiter && source[i++] != '\0');
  len = i-c+1;

  *target = ssh_xmalloc(len);

  memcpy(*target, &source[c], len-1);
  (*target)[len-1] = '\0';

  return *target;
}
Exemplo n.º 2
0
static Boolean hex_string_to_data(char *str,
                                  unsigned char **data,
                                  size_t *data_len)
{
  size_t str_len, buf_len;
  unsigned char *buf;
  int i, ch, cl;

  str_len = strlen(str);
  if ((str_len == 0) || ((str_len % 2) != 0))
    return FALSE;
  buf_len = str_len / 2;
  buf = ssh_xmalloc(buf_len);
  for (i = 0; i < buf_len; i++)
    {
      ch = hex_char_to_int(str[i * 2]);
      cl = hex_char_to_int(str[(i * 2) + 1]);
      if ((ch >= 0) && (cl >= 0))
        {
          buf[i] = (unsigned char)(ch * 16 + cl);
        }
      else
        {
          ssh_xfree(buf);
          return FALSE;
        }
    }
  if (data)
    *data = buf;
  else
    ssh_xfree(buf);
  if (data_len)
    *data_len = buf_len;
  return TRUE;
}
Exemplo n.º 3
0
void ssh_local_connect(const char *path,
                       SshLocalCallback callback,
                       void *context)
{
    int sock;
    SshLocalConnect c;

    /* Create a unix-domain socket. */
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0)
    {
        /* Failed to create the socket. */
        (*callback)(NULL, context);
        return;
    }

    /* Allocate and initialize a context structure. */
    c = ssh_xmalloc(sizeof(*c));
    c->path = ssh_xstrdup(path);
    c->sock = sock;
    c->callback = callback;
    c->context = context;

    /* Register the file descriptor.  Note that this also makes it
       non-blocking. */
    ssh_io_register_fd(sock, ssh_local_connect_try, c);

    /* Fake a callback to start asynchronous connect. This connect could be
       done on this current routine, but we want this to be similar with
       tcp/ip socket code, so we use the try-routines */
    ssh_local_connect_try(SSH_IO_WRITE, (void *)c);
}
Exemplo n.º 4
0
SshBuffer *ssh_buffer_allocate()
{
  SshBuffer *buffer = ssh_xmalloc(sizeof(*buffer));
  ssh_buffer_init(buffer);
  buffer->dynamic = TRUE;
  return buffer;
}
Exemplo n.º 5
0
/* Allocate a file buffer */
SshFileBuffer ssh_file_buffer_allocate(void)
{
  SshFileBuffer r;

  r = ssh_xmalloc(sizeof (*r));
  ssh_file_buffer_init(r);
  return r;
}
Exemplo n.º 6
0
SshLocalListener ssh_local_make_listener(const char *path,
        SshLocalCallback callback,
        void *context)
{
    int sock;
    struct sockaddr_un sunaddr;
    SshLocalListener listener;

    /* Create a socket for the listener. */
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0)
    {
        ssh_warning("Can not create local domain socket: %.200s",
                    strerror(errno));
        return NULL;

    }

    /* Initialize a unix-domain address structure. */
    memset(&sunaddr, 0, sizeof(sunaddr));
    sunaddr.sun_family = AF_UNIX;
    strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));

    /* Bind the socket to the address.  This will create the socket in the file
       system, and will fail if the socket already exists. */
    if (bind(sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)) < 0)
    {
        close(sock);
        ssh_warning("Can not bind local address %.200s: %.200s",
                    path, strerror(errno));
        return NULL;
    }

    /* Start listening for connections to the socket. */
    if (listen(sock, 5) < 0)
    {
        close(sock);
        ssh_warning("Can not listen to local address %.200s: %.200s",
                    path, strerror(errno));
        return NULL;
    }

    /* Allocate and initialize the listener structure. */
    listener = ssh_xmalloc(sizeof(*listener));
    listener->sock = sock;
    listener->path = ssh_xstrdup(path);
    listener->callback = callback;
    listener->context = context;

    /* ssh_local_listen_callback will call the user supplied callback
       when after new connection is accepted. It also creates stream
       object for the new connection and calls callback. */
    ssh_io_register_fd(sock, ssh_local_listen_callback, (void *)listener);
    ssh_io_set_fd_request(sock, SSH_IO_READ);

    return listener;
}
Exemplo n.º 7
0
void ssh_buffer_init(SshBuffer *buffer)
{
  SSH_ASSERT(buffer);

  buffer->alloc = 4096;
  buffer->buf = ssh_xmalloc(buffer->alloc);
  buffer->offset = 0;
  buffer->end = 0;
  buffer->dynamic = FALSE;
}
Exemplo n.º 8
0
void *ssh_xstrdup(const void *p)
{
  const char *str;
  char *cp;

  SSH_ASSERT(p != NULL);
  str = (const char *)p;
  cp = ssh_xmalloc(strlen(str) + 1);
  strcpy(cp, str);
  return (void *)cp;
}
Exemplo n.º 9
0
void open_windows()
{
  int i; int scrap;
  XSetWindowAttributes attributes;
  XSizeHints *hints = XAllocSizeHints();

  attributes.backing_store = WhenMapped;
  attributes.cursor = XCreateFontCursor(display, XC_X_cursor);

  main_window = XCreateWindow(display, DefaultRootWindow(display),
                              w_x, w_y, w_width, w_height, 0,
                              CopyFromParent, InputOutput,
                              CopyFromParent, CWCursor | CWBackingStore,
                              &attributes);

  hints->flags = PPosition | PSize | PMinSize | PMaxSize | PWinGravity;
  hints->x = w_x; hints->y = w_y;
  hints->width = w_width; hints->height = w_height;
  hints->min_width = hints->max_width = w_width;
  hints->min_height = hints->max_height = w_height;
  hints->win_gravity = CenterGravity;
  XSetWMNormalHints(display, main_window, hints);

  XStoreName(display, main_window, "SSH Authentication Passphrase Request");

  /* This is a dialog box, I think. */
  XSetTransientForHint(display, main_window,
                       DefaultRootWindow(display));
  XFree(hints);

  cancel_button = XCreateWindow(display, main_window,
                                w_width - relief - margin - b_width,
                                w_height - relief - margin - b_height,
                                b_width, b_height,
                                0,
                                CopyFromParent, InputOutput,
                                CopyFromParent, CWCursor |
                                CWBackingStore,
                                &attributes);
  
  leds = (w_width - relief * 2 - margin * 2 + (led_width - led_i_width)) /
    led_width;
  scrap = (w_width - relief * 2 - margin * 2 + (led_width - led_i_width)) %
    led_width;
  leds_x = relief + margin + scrap/2;

  led_state = ssh_xmalloc(sizeof(int) * leds);
  for (i = 0; i < leds; i++) led_state[i] = 0;
  
  attributes.cursor = XCreateFontCursor(display, XC_top_left_arrow);
  XChangeWindowAttributes(display, cancel_button, CWCursor | CWBackingStore,
                          &attributes);
}
Exemplo n.º 10
0
void *ssh_xmemdup(const void *p, unsigned long len)
{
  const char *str = (const char *)p;
  char *cp;
  
  if (len > XMALLOC_MAX_SIZE)
    ssh_fatal("ssh_xmemdup: allocation too large (allocating %ld bytes)", len);
  
  cp = ssh_xmalloc(len + 1);
  memcpy(cp, str, (size_t)len);
  cp[len] = '\0';
  return (void *)cp;
}
Exemplo n.º 11
0
SshMutex ssh_mutex_create(const char *name, SshUInt32 flags)
{
  SshMutex mutex;

  mutex = ssh_xmalloc(sizeof(*mutex));
  InitializeCriticalSection(&mutex->critical);
  if (name)
    mutex->name = ssh_xstrdup(name);
  else
    mutex->name = NULL;
  mutex->locked = 0;
  return mutex;
}
Exemplo n.º 12
0
Arquivo: sshurl.c Projeto: AnthraX1/rk
/* Parse one key=value pair, returns TRUE if decoding was successfull, and
   inserts the decoded key value pair to the mapping.*/
Boolean ssh_url_parse_one_item(SshMapping mapping, const char *item,
                               size_t len)
{
  const char *key, *value;
  size_t key_len, value_len;
  char *decoded_key, *decoded_value, *old_value;
  size_t decoded_key_len, decoded_value_len, old_value_len;
  Boolean ok = TRUE;

  if (len == 0)
    return FALSE;
  key = item;
  value = strchr(item, '=');
  if (value - item > len)
    {
      key_len = len;
      value = item;
      value_len = 0;
    }
  else
    {
      key_len = value - key;
      value++;
      value_len = len - key_len - 1;
    }
  if (!ssh_url_decode_bin((char *) key, key_len,
                          &decoded_key, &decoded_key_len))
    ok = FALSE;
  if (!ssh_url_decode_bin((char *) value, value_len,
                          &decoded_value, &decoded_value_len))
    ok = FALSE;

  if (ssh_mapping_get_vl(mapping, decoded_key, decoded_key_len,
                         (void *) &old_value, &old_value_len))
    {
      char *p;

      /* Concatenate strings and separate items with a '\n' character.
         Make the result null terminated */
      p = ssh_xmalloc(old_value_len + decoded_value_len + 2);
      memmove(p, old_value, old_value_len);
      p[old_value_len] = '\n';
      memmove(p + old_value_len + 1, decoded_value, decoded_value_len + 1);
      decoded_value_len = old_value_len + decoded_value_len + 1;
      ssh_xfree(decoded_value);
      decoded_value = p;
    }
  ssh_mapping_put_vl(mapping, decoded_key, decoded_key_len,
                     decoded_value, decoded_value_len);
  return ok;
}
Exemplo n.º 13
0
/* Handle the parsing of the single line string. */
static size_t
ssh_key_blob_get_line(const unsigned char *buf, size_t len,
                      char **string)
{
  size_t i, step, keep;
  SshBufferStruct buffer;

  ssh_buffer_init(&buffer);
  for (i = 0, step = 0, keep = 0; i < len; i++)
    {
      switch (buf[i])
        {
        case '\n':
          /* End. */
          step = i;
          goto end;
        case ' ':
        case '\t':
        case '\r':
          if (ssh_buffer_len(&buffer) == 0)
            {
              keep = 0;
              break;
            }
          keep = 1;
          break;
        default:
          if (keep)
            {
              ssh_xbuffer_append(&buffer, (const unsigned char *)" ", 1);
              keep = 0;
            }
          ssh_xbuffer_append(&buffer, &buf[i], 1);
          break;
        }
    }

end:

  /* Make a string. */
  *string = ssh_xmalloc(ssh_buffer_len(&buffer) + 1);
  memcpy(*string, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
  (*string)[ssh_buffer_len(&buffer)] = '\0';

  ssh_buffer_uninit(&buffer);

  return step;
}
Exemplo n.º 14
0
SshThread fork_thread(SshForkedFunc func, void *context)
{
  SshThread t;
  DWORD thread_id;
  HANDLE handle;

  t = (SshThread)ssh_xmalloc(sizeof(*t));
  t->func = func;
  t->func_context = context;
  if (!(handle = CreateThread(NULL, 0, thread_func, t, 0, &thread_id)))
    {
      ssh_xfree(t);
      return NULL;
    }
  t->thread_id = thread_id;
  t->handle = handle;
  return t;
}
Exemplo n.º 15
0
char *ssh_generate_name_from_buffer(const char *name,
                                    const unsigned char *blob,
                                    size_t bloblen)
{
  unsigned char *ret;
  size_t namelen;
  SshUInt32 crc;

  if (!name)
    name = "???";
  namelen = strlen(name);
  crc = crc32_buffer(blob, bloblen);
  ret = ssh_xmalloc(namelen + 10);
  ssh_ustrncpy(ret, ssh_custr(name), namelen);
  ret[namelen] = ' ';
  ssh_snprintf(ret + namelen + 1, 9, "%08lx", (unsigned long)crc);
  return (char *) ret;
}
Exemplo n.º 16
0
void copy_reader(SshStreamNotification op, void *context)
{
  unsigned char *buf;
  int len;

  if (op != SSH_STREAM_INPUT_AVAILABLE)
    return;

  buf = ssh_xmalloc(T_STREAMPAIR_BIG_BUF_LEN);

  for (;;)
    {
      len = ssh_stream_read(ts2, buf, T_STREAMPAIR_BIG_BUF_LEN);
      if (len == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return; /* EOF received */
        }
      if (len < 0)
        {
          ssh_xfree(buf);
          return;
        }
      ssh_buffer_append(received_data, buf, len);
      if (break_test && ssh_rand() % 10 == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return;
        }
      if (!reader_sent_eof && ssh_rand() % 10 == 0)
        {
          ssh_stream_output_eof(ts2);
          reader_sent_eof = TRUE;
        }
    }
  /*NOTREACHED*/
}
Exemplo n.º 17
0
SshTransportParams ssh_transport_create_params(void)
{
  SshTransportParams params;
  char *hlp;

  params = ssh_xmalloc(sizeof(*params));
  params->kex_algorithms = ssh_xstrdup(DEFAULT_KEXS);
  hlp = ssh_public_key_get_supported();
  params->host_key_algorithms = ssh_public_key_list_canonialize(hlp);
  ssh_xfree(hlp);
  params->hash_algorithms = ssh_hash_get_supported();
  params->compressions_c_to_s = ssh_xstrdup(DEFAULT_COMPRESSIONS);
  params->compressions_s_to_c = ssh_xstrdup(DEFAULT_COMPRESSIONS);
  params->ciphers_c_to_s = ssh_name_list_intersection_cipher(DEFAULT_CIPHERS);
  params->ciphers_s_to_c = ssh_name_list_intersection_cipher(DEFAULT_CIPHERS);
  params->macs_c_to_s = ssh_name_list_intersection_mac(DEFAULT_MACS);
  params->macs_s_to_c = ssh_name_list_intersection_mac(DEFAULT_MACS);
  return params;
}
Exemplo n.º 18
0
/* Convert from a hex string to unsigned char buffer */
static void hex_string_to_buf(const char *str,
			      unsigned char **key, 
			      size_t *keylen)
                           
{
  unsigned char *buf, c, d;
  size_t len, i;

  SSH_DEBUG(5, ("Convert %s to buffer\n", str));

  SSH_ASSERT(strlen(str) % 2 == 0);

  len = strlen(str) / 2; 
  buf = ssh_xmalloc(len); 

  for (i = 0; i < len; i++)
    {
      c = tolower(str[2*i]);
      d = tolower(str[2*i + 1]);

      SSH_ASSERT(isxdigit(c));
      SSH_ASSERT(isxdigit(d));

      if (islower(c)) 
        buf[i] = (c - 'a') + 10;
      else 
        buf[i] = (c - '0');
      
      buf[i] <<= 4; 

      if (islower(d)) 
        buf[i] += (d - 'a') + 10;
      else 
        buf[i] += (d - '0');
    }  

  *key = buf;
  *keylen = len;
  return;
}
Exemplo n.º 19
0
SshStream ssh_stream_fd_wrap2(int readfd, int writefd,
			      Boolean close_on_destroy)
{
  SshFdStream sdata;

  sdata = ssh_xmalloc(sizeof(*sdata));
  memset(sdata, 0, sizeof(*sdata));
  sdata->readfd = readfd;
  sdata->writefd = writefd;
  sdata->close_on_destroy = close_on_destroy;
  sdata->read_has_failed = FALSE;
  sdata->write_has_failed = FALSE;
  sdata->destroyed = FALSE;
  sdata->in_callback = FALSE;
  sdata->keep_nonblocking = FALSE;
  sdata->callback = NULL;
  if (readfd >= 0)
    ssh_io_register_fd(readfd, ssh_stream_fd_callback, (void *)sdata);
  if (readfd != writefd && writefd >= 0)
    ssh_io_register_fd(writefd, ssh_stream_fd_callback, (void *)sdata);
  return ssh_stream_create(&ssh_stream_fd_methods, (void *)sdata);
}
Exemplo n.º 20
0
void
ssh_virtual_adapter_send(SshInterceptor interceptor,
			    SshInterceptorPacket pp)
{
  unsigned char *packet, *internal;
  size_t packet_len, internal_len;

  /* Linearize the packet. */

  packet_len = ssh_interceptor_packet_len(pp);
  packet = ssh_xmalloc(packet_len);

  ssh_interceptor_packet_copyout(pp, 0, packet, packet_len);

  if (!ssh_interceptor_packet_export_internal_data(pp, &internal,
                                                   &internal_len))
    return;

  SSH_DEBUG(SSH_D_NICETOKNOW, 
	    ("sending send request for virtual adapter %d to forwarder.",
	     (int) pp->ifnum_out));

  /* Send the packet to the kernel forwarder module. */
  ssh_usermode_interceptor_send_encode(
                        interceptor,
                        SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_SEND,
			SSH_FORMAT_UINT32, pp->ifnum_in,
                        SSH_FORMAT_UINT32, pp->ifnum_out,
                        SSH_FORMAT_UINT32, pp->protocol,
                        SSH_FORMAT_UINT32_STR, packet, packet_len,
                        SSH_FORMAT_UINT32_STR, internal, internal_len,
                        SSH_FORMAT_END);

  /* Free the linearized packet. */
  ssh_xfree(packet);

  /* Free the original packet object. */
  ssh_interceptor_packet_free(pp);
}
Exemplo n.º 21
0
/* 
 * Initializes audit context. Calling function MUST remember to release memory
 * reserved for context structure. params contains parameters for initialized 
 * context. These are:
 * win_syslog_source_name - Name passed to windows system log may be NULL if 
 *                          not used. In unix NOT defined
 * log_filename - Name for the file used to store audit events may be NULL 
 *                if not used
 * If neither Windows system log or log_filename is defined ssh_log_event()
 * function is used as a default. It takes facility and severity as a 
 * parameter. 
 */
SshAuditContext ssh_audit_init(SshAuditParams params)
{
  SshAuditContext context;
  int i;

  context = ssh_xmalloc(sizeof(struct SshAuditContextRec));
#ifdef WIN32
  context->win_syslog_source_name = params->win_syslog_source_name;
#endif /* WIN32 */
  context->log_filename = params->log_filename;
  context->facility = params->facility;
  context->severity = params->severity;
  if (context->log_filename)
    context->out_file = fopen((char *) context->log_filename, "a+wt");
  else
    context->out_file = NULL;

  /* Allow all events to be audited */
  for(i=0; i < SSH_AUDIT_MAX_VALUE; i++) 
    context->ssh_audit_event_allowed[i] = TRUE;
  return context;
}
Exemplo n.º 22
0
/* Decoding of the SSH2 ascii key blob format. */
unsigned long
ssh2_key_blob_decode(unsigned char *data, size_t len,
                     Boolean try_convert_ssh1_cert,
                     char **subject,
                     char **comment,
                     unsigned char **blob, size_t *bloblen)
{
  unsigned char *tmp, *whitened;
  char *my_name, *my_comment;
  size_t step, start, end, start2, end2;
  unsigned long magic, magic2;

  /* Match first the heading. */
  magic = ssh_key_blob_match(data, len,
                             0, /* head */
                             &start, &end);


  if (magic == SSH_KEY_MAGIC_FAIL)
    goto fail;

  /* Match then the tail. */
  magic2 = ssh_key_blob_match(data, len,
                              1, /* tail */
                              &start2, &end2);

  if (magic2 != magic)
    goto fail;

  if ((magic != SSH_KEY_MAGIC_SSH1_PUBLIC) &&
      (magic != SSH_KEY_MAGIC_SSH1_PRIVATE) &&
      (magic != SSH_KEY_MAGIC_SSH1_PRIVATE_ENCRYPTED))
    {
      /* Check. */
      if (len - end == 0)
        goto fail;

      /* Read the keywords. */
      step = ssh_key_blob_keywords(data + end + 1, len - end - 1,
                                   &my_name, &my_comment);

      /* If name is available pass it up. */
      if (subject)
        *subject = my_name;
      else
        ssh_xfree(my_name);

      /* If comment is available pass it up. */
      if (comment)
        *comment = my_comment;
      else
        ssh_xfree(my_comment);

      /* Convert the remainder to a string. */
      tmp = ssh_xmalloc(start2 - end - step);
      memcpy(tmp, data + end + 1 + step, start2 - end - step - 1);

      /* Remove whitespace. */
      whitened = ssh_base64_remove_whitespace(tmp, start2 - end - step - 1);
      ssh_xfree(tmp);

      /* Decode the base64 blob. */
      *blob = ssh_base64_to_buf(whitened, bloblen);
      ssh_xfree(whitened);
      ssh_xfree(data);
    }
#ifdef SSHDIST_APPUTIL_SSH1ENCODE
  else if ((magic == SSH_KEY_MAGIC_SSH1_PUBLIC) &&
           (try_convert_ssh1_cert != FALSE))
    {
      SshPublicKey tmpkey;
      unsigned char *tmpblob;
      size_t tmpbloblen;

      if (ssh1_decode_pubkeyblob(data, len, &my_comment, &tmpkey)
          == SSH_CRYPTO_OK)
        {
          tmpbloblen = ssh_encode_pubkeyblob(tmpkey, &tmpblob);
          ssh_public_key_free(tmpkey);
          if (tmpbloblen > 0)
            {
              ssh_xfree(data);
              data = tmpblob;
              len = tmpbloblen;
              magic = SSH_KEY_MAGIC_PUBLIC;
              SSH_DEBUG(5, ("converted ssh1 pubkey to ssh2 certs"));
            }
          else
            {
              ssh_xfree(my_comment);
              goto fail;
            }
        }
      else
        {
          goto fail;
        }
      if (comment)
        *comment = my_comment;
      else
        ssh_xfree(my_comment);
      *blob = data;
      if (bloblen)
        *bloblen = len;
    }
  else if (magic == SSH_KEY_MAGIC_SSH1_PUBLIC)
    {
      SshPublicKey tmpkey;
      unsigned char *tmpblob;
      size_t tmpbloblen;

      if (ssh1_decode_pubkeyblob(data, len, &my_comment, &tmpkey)
          == SSH_CRYPTO_OK)
        {
          size_t l;
          SshMPIntegerStruct e, n;
          char *estr, *nstr;

          ssh_mprz_init(&e);
          ssh_mprz_init(&n);
          if (ssh_public_key_get_info(tmpkey,
                                      SSH_PKF_MODULO_N, &n,
                                      SSH_PKF_PUBLIC_E, &e,
                                      SSH_PKF_END) == SSH_CRYPTO_OK)
            {
              ssh_public_key_free(tmpkey);
              l = ssh_mprz_get_size(&n, 2);
              estr = ssh_mprz_get_str(&e, 10);
              nstr = ssh_mprz_get_str(&n, 10);
              ssh_mprz_clear(&e);
              ssh_mprz_clear(&n);
              tmpbloblen = ssh_xdsprintf(&tmpblob,
                                         "%u %s %s -",
                                         (unsigned int)l,
                                         estr,
                                         nstr);
              ssh_xfree(estr);
              ssh_xfree(nstr);
            }
          else
            {
              ssh_public_key_free(tmpkey);
              ssh_mprz_clear(&e);
              ssh_mprz_clear(&n);
              ssh_xfree(my_comment);
              goto fail;
            }
          data = tmpblob;
          len = tmpbloblen;
        }
      else
        {
          goto fail;
        }
      if (comment)
        *comment = my_comment;
      else
        ssh_xfree(my_comment);
      *blob = data;
      if (bloblen)
        *bloblen = len;
    }
#endif /* SSHDIST_APPUTIL_SSH1ENCODE */
  else
    {
      /* If it's an ssh1 private key we just push entire blob up. */
      *blob = data;
      if (bloblen)
        *bloblen = len;
    }
  SSH_DEBUG(5, ("key blob magic = 0x%08lx", magic));
  return magic;

fail:
  ssh_xfree(data);
  return SSH_KEY_MAGIC_FAIL;
}
Exemplo n.º 23
0
/* Handle the quoted string parsing. */
size_t
ssh_key_blob_get_string(const unsigned char *buf, size_t len,
                        char **string)
{
  unsigned int quoting, ret_quoting;
  SshBufferStruct buffer;
  size_t step, i, j;

  ssh_buffer_init(&buffer);
  for (i = 0, step = 0, quoting = 0, ret_quoting = 0; i < len; i++)
    {
      switch (quoting)
        {
        case 0:
          switch (buf[i])
            {
            case ' ':
            case '\n':
            case '\r':
            case '\t':
              /* Skip! */
              break;
            case '\"': /* " */
              quoting = 2;
              ret_quoting = 0;
              break;
            default:
              /* End! */
              step = i;
              goto end;
            }
          break;
        case 1:
          if (buf[i] == '\n')
            {
              for (j = 0; isspace(buf[i + j]) && i + j < len;
                   j++)
                ;
              i = i + j - 1;
            }
          quoting = ret_quoting;
          ret_quoting = 0;
          break;
        case 2:
          switch (buf[i])
            {
            case '\\':
              quoting = 1;
              ret_quoting = 2;
              break;
            case '\"': /* " */
              quoting = 0;
              ret_quoting = 0;
              break;
            default:
              ssh_xbuffer_append(&buffer, &buf[i], 1);
              break;
            }
        }
    }

end:

  /* Make a string. */
  *string = ssh_xmalloc(ssh_buffer_len(&buffer) + 1);
  memcpy(*string, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
  (*string)[ssh_buffer_len(&buffer)] = '\0';

  ssh_buffer_uninit(&buffer);

  return step;
}
Exemplo n.º 24
0
void ssh_client_auth_hostbased(SshAuthClientOperation op,
                               const char *user,
                               unsigned int packet_type,
                               SshBuffer *packet_in,
                               const unsigned char *session_id,
                               size_t session_id_len,
                               void **state_placeholder,
                               SshAuthClientCompletionProc completion,
                               void *completion_context,
                               void *method_context)
{
  SshClientHostbasedAuth state;
  SshClient client;
  SshStream stdio_stream;
  char hostkeyfile[512];
  /*  char *keytype;
  SshPublicKey pubkey;*/
  char **signer_argv;
  char config_filename[512];
  size_t hostname_len;
  
  SSH_DEBUG(6, ("auth_hostbased op = %d  user = %s", op, user));

  client = (SshClient)method_context;
  state = *state_placeholder;

  switch (op)
    {
      /* This operation is always non-interactive, as hostkeys
         shouldn't have passphrases. Check for it, though. XXX */
    case SSH_AUTH_CLIENT_OP_START_NONINTERACTIVE:
      /* XXX There is a bug in sshauthc.c (or
         elsewhere). Authentication methods, that are not allowed,
         should not be tried. Now it calls
         SSH_AUTH_CLIENT_OP_START_NONINTERACTIVE for every
         authentication method before checking.*/
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      break;
      
    case SSH_AUTH_CLIENT_OP_START:
      /* This is the first operation for doing hostbased authentication.
         We should not have any previous saved state when we come here. */
      SSH_ASSERT(*state_placeholder == NULL);

      /* Initialize a context. */
      state = ssh_xcalloc(1, sizeof(*state));

      state->session_id = session_id;
      state->session_id_len = session_id_len;
      state->user = ssh_xstrdup(user);

      /* We have to dig up the server configuration to get the place
         for the client host's publickey. This is a very kludgeish
         solution. XXX*/
      state->server_conf = ssh_server_create_config();
      
      /* Dig up hosts publickey. */
      
      snprintf(config_filename, sizeof(config_filename), "%s/%s",
               SSH_SERVER_DIR, SSH_SERVER_CONFIG_FILE);
      
      if (!ssh_config_read_file(client->user_data, state->server_conf,
                                NULL, config_filename, NULL))
        SSH_TRACE(2, ("Failed to read config file %s", \
                      config_filename));


      if(state->server_conf->public_host_key_file[0] != '/')
        {
          snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                   state->server_conf->public_host_key_file);
        }
      else
        {
          snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                   state->server_conf->public_host_key_file);  
        }

      /* This pubkey*-stuff is for the client _host's_ public
         hostkey. */
      SSH_DEBUG(4, ("Reading pubkey-blob from %s...", hostkeyfile));
      if (ssh2_key_blob_read(client->user_data, hostkeyfile, NULL,
                             &state->pubkeyblob,
                             &state->pubkeyblob_len, NULL) 
          != SSH_KEY_MAGIC_PUBLIC)
        {         
          goto error;
        }
      
      SSH_DEBUG(4, ("done."));
      if ((state->pubkey_algorithm =
           ssh_pubkeyblob_type(state->pubkeyblob,
                               state->pubkeyblob_len))
          == NULL)
        {
          goto error;
        }
      
      state->local_user_name = ssh_user_name(client->user_data);
      state->local_host_name = ssh_xmalloc(MAXHOSTNAMELEN + 1);
      ssh_tcp_get_host_name(state->local_host_name, MAXHOSTNAMELEN + 1);
      hostname_len = strlen(state->local_host_name);
      /* Sanity check */
      SSH_ASSERT(hostname_len + 2 < MAXHOSTNAMELEN);
      /* We want FQDN. */
      state->local_host_name[hostname_len] = '.';
      state->local_host_name[hostname_len + 1] = '\0';
      
      state->completion = completion;
      state->completion_context = completion_context;
      state->state_placeholder = state_placeholder;
      
      /* Assign the state to the placeholder that survives across
         calls.  (this is actually not needed, as hostbased
         authentication procedure is very simple. Just one packet from
         client to server, and server's response in one packet.) */
      *state_placeholder = state;

      /* Open a pipestream connection to ssh-signer. */
      switch (ssh_pipe_create_and_fork(&stdio_stream, NULL))
        {
        case SSH_PIPE_ERROR:
          /* Something went wrong. */
          ssh_warning("Couldn't create pipe to connect to %s.",
                      client->config->signer_path);
          goto error;
          break;
        case SSH_PIPE_CHILD_OK:
          /* Exec ssh-signer */
          SSH_TRACE(0, ("Child: Execing ssh-signer...(path: %s)", \
                        client->config->signer_path));

          signer_argv = ssh_xcalloc(2, sizeof(char *));
          signer_argv[0] = client->config->signer_path;
          signer_argv[1] = NULL;
          
          execvp(client->config->signer_path, signer_argv);
          fprintf(stderr, "Couldn't exec '%s' (System error message: %s)",
                  client->config->signer_path, strerror(errno));
          ssh_fatal("Executing ssh-signer failed.");
          break;
        case SSH_PIPE_PARENT_OK:
          state->wrapper = ssh_packet_wrap(stdio_stream,
                                           auth_hostbased_received_packet,
                                           auth_hostbased_received_eof,
                                           auth_hostbased_can_send,
                                           state);
          /* We don't check wrapper's validity, as ssh_packet_wrap
             should always succeed.*/
          break;
        }
      /* Here we continue as parent. */
      
      /* sign packet with ssh-signer (a suid-program). */
      if (ssh_packet_wrapper_can_send(state->wrapper))
        {
          ssh_client_auth_hostbased_send_to_signer(state);
        }
      /* If ssh_packet_wrapper_can_send returns FALSE,
         auth_hostbased_can_send will call the ...send_to_signer
         function above. */
      
      /* Rest is done in callbacks. */
      break;
      
    case SSH_AUTH_CLIENT_OP_CONTINUE:          
      SSH_TRACE(2, ("Invalid message. We didn't return " \
                    "SSH_AUTH_CLIENT_SEND_AND_CONTINUE at any stage!"));
      /* Send failure message.*/
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      return;

    case SSH_AUTH_CLIENT_OP_ABORT:
      /* Abort the authentication operation immediately. */
      /* XXX Destroy 'state'-object. */
      *state_placeholder = NULL;
      break;

    default:
      /* something weird is going on.. */
      ssh_fatal("ssh_client_auth_hostbased: unknown op %d", (int)op);
    }
  return;

 error:
  /* XXX Destroy state. */
  /* Send failure message.*/
  (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
  return;
}
Exemplo n.º 25
0
int main(int ac, char **av)
{
  unsigned int pass, i;
  SshBuffer buffer, buffer2;
  SocksInfo socksinfo, socksreturn;
  SocksError ret;

  ssh_buffer_init(&buffer);
  ssh_buffer_init(&buffer2);
  for(pass = 0; pass < 20000; pass++)
    {
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  if (ssh_socks_server_parse_open(&buffer, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (socksinfo->socks_version_number != socksreturn->socks_version_number)
	ssh_fatal("socks_version_numbers differ request");
      if (socksinfo->command_code != socksreturn->command_code)
	ssh_fatal("command_codes differ request");
      if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	ssh_fatal("ip numbers differ request");
      if (strcmp(socksinfo->port, socksreturn->port) != 0)
	ssh_fatal("port numbers differ request");
      if (strcmp(socksinfo->username, socksreturn->username) != 0)
	ssh_fatal("usernames differ request");
      ssh_socks_free(&socksreturn);
      ssh_socks_free(&socksinfo);
      
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_client_parse_reply(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  ret = ssh_socks_client_parse_reply(&buffer2, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails for partial data");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  ret = ssh_socks_client_parse_reply(&buffer, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (ret == SSH_SOCKS_SUCCESS)
	{
	  if (socksinfo->socks_version_number !=
	      socksreturn->socks_version_number)
	    ssh_fatal("socks_version_numbers differ reply");
	  if (socksinfo->command_code != socksreturn->command_code)
	    ssh_fatal("command_codes differ reply");
	  if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	    ssh_fatal("ip numbers differ reply");
	  if (strcmp(socksinfo->port, socksreturn->port) != 0)
	    ssh_fatal("port numbers differ reply");
	  ssh_socks_free(&socksreturn);
	}
      ssh_socks_free(&socksinfo);
    }
  
  ssh_buffer_clear(&buffer);
  
  for(pass = 0;
      pass < (sizeof(ip_invalid_numbers) / sizeof(ip_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_invalid_numbers[pass % (sizeof(ip_invalid_numbers) /
					   sizeof(ip_invalid_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, ip)");
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, ip)");
      ssh_socks_free(&socksinfo);
    }
  for(pass = 0;
      pass < (sizeof(port_invalid_numbers) / sizeof(port_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_invalid_numbers[pass % (sizeof(port_invalid_numbers) /
					     sizeof(port_invalid_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, port)");
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->socks_version_number = 0;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, port)");
      ssh_socks_free(&socksinfo);
    }
  if (ssh_buffer_len(&buffer) != 0)
    ssh_fatal("some of the failed ssh_socks_*_generate_* function wrote something to buffer, size != 0");
  ssh_buffer_uninit(&buffer);
  ssh_buffer_uninit(&buffer2);
  return 0;
}
Exemplo n.º 26
0
Boolean ssh_pgp_read_packet(SshFileBuffer *filebuf, SshPgpPacket *packet)
{
  unsigned char type_id;
  int packet_type;
  int i;
  size_t l;
  Boolean fr;
  Boolean partial_body;
  SshPgpPacket newpacket;
  SshBuffer partial_buf;
  Boolean partial_buf_init;

  partial_buf_init = FALSE;

  do {
    fr = ssh_file_buffer_expand(filebuf, 1);
    if (fr == FALSE)
      goto failed;
    type_id = *(ssh_buffer_ptr(&(filebuf->buf)));
    ssh_buffer_consume(&(filebuf->buf), 1);
    
    SSH_DEBUG(5, ("type_id = %d\n", type_id));

    if (type_id & 0x40) 
      {
        /* New packet header format */
        SSH_DEBUG(5, ("New packet header format\n"));
        if (partial_buf_init == FALSE)
          packet_type = type_id & 0x7f;
        fr = ssh_file_buffer_expand(filebuf, 1);
        if (fr == FALSE)
          goto failed;
        l = *(ssh_buffer_ptr(&(filebuf->buf)));
        ssh_buffer_consume(&(filebuf->buf), 1);
        if ((l >= 192) && (l <= 223))
          {
            partial_body = FALSE;
            fr = ssh_file_buffer_expand(filebuf, 1);
            if (fr == FALSE)
              goto failed;
            l = (((l - 192) << 8) + 
                 ((size_t)(*(ssh_buffer_ptr(&(filebuf->buf))))) +
                 192);
            ssh_buffer_consume(&(filebuf->buf), 1);
          }
        else if ((l >= 224) && (l <= 254))
          {
            partial_body = TRUE;
            fr = ssh_file_buffer_expand(filebuf, 1);
            if (fr == FALSE)
              goto failed;
            l = ((size_t)1) << ((*(ssh_buffer_ptr(&(filebuf->buf)))) & 0x1f);
            ssh_buffer_consume(&(filebuf->buf), 1);
            if (partial_buf_init == FALSE)
              {
                ssh_buffer_init(&partial_buf);
                partial_buf_init = TRUE;
              }
          }
        else if (l == 255)
          {
            partial_body = FALSE;
            l = 0;
            fr = ssh_file_buffer_expand(filebuf, 4);
            if (fr == FALSE)
              goto failed;
            for (i = 0; i < 4; i++)
              {
                l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf))));
                ssh_buffer_consume(&(filebuf->buf), 1);
              }
          }
        else
          {
            partial_body = FALSE;
          }
      }
    else
      {
        size_t ll;

        /* Old packet header format */
        SSH_DEBUG(5, ("Old packet header format\n"));
        partial_body = FALSE;
        if (partial_buf_init == FALSE)
          packet_type = (type_id & 0x7c) >> 2;
        ll = ((int)1) << (type_id & 0x03);
        fr = ssh_file_buffer_expand(filebuf, (int)ll);
        if (fr == FALSE)
          goto failed;
        l = 0;
        for (i = 0; i < ll; i++) {
          l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf))));
          ssh_buffer_consume(&(filebuf->buf), 1);
        }
      }

    if ((l < 1) || (l > 0x4000)) /* XXX */
      goto failed; 

    fr = ssh_file_buffer_expand(filebuf, l);
    if (fr == FALSE)
      goto failed;
    if (partial_body == FALSE)
      {
        if (packet != NULL) 
          {
            newpacket = ssh_xmalloc(sizeof (struct SshPgpPacketRec));
            newpacket->type = packet_type;
            if (partial_buf_init)
              {
                newpacket->len = l + ssh_buffer_len(&partial_buf);
                newpacket->data = ssh_xmalloc(newpacket->len);
                memcpy(newpacket->data, 
                       ssh_buffer_ptr(&partial_buf),
                       ssh_buffer_len(&partial_buf));
                memcpy(&(newpacket->data[ssh_buffer_len(&partial_buf)]), 
                       ssh_buffer_ptr(&(filebuf->buf)), 
                       l);
                ssh_buffer_uninit(&partial_buf);
                partial_buf_init = FALSE;
              }
            else
              {
                newpacket->len = l;
                newpacket->data = ssh_xmalloc(l);
                memcpy(newpacket->data, ssh_buffer_ptr(&(filebuf->buf)), l);
              }
            *packet = newpacket;
            ssh_buffer_consume(&(filebuf->buf), l);
          }
      }
    else
      {
        ssh_buffer_append(&partial_buf, ssh_buffer_ptr(&(filebuf->buf)), l);
        ssh_buffer_consume(&(filebuf->buf), l);
      }
  } while (partial_body == TRUE);

  return TRUE;

 failed:
  if (partial_buf_init == TRUE)
    ssh_buffer_uninit(&partial_buf);
  return FALSE;
}
Exemplo n.º 27
0
int main(int argc, char* argv[])
{
  t_tcpc_context  pcontext = 0;
  SshGetOptData   pgetoptdata = 0;
  int                             i;

  SSH_TRACE(SSH_D_MY, ("%s", "main"));

  pcontext = ssh_xmalloc(sizeof (*pcontext));
  memset(pcontext, 0, sizeof (*pcontext));

  pgetoptdata = ssh_xmalloc(sizeof (*pgetoptdata));
  memset(pgetoptdata, 0, sizeof (*pgetoptdata));

  ssh_getopt_init_data(pgetoptdata);
  pcontext->pport_or_service = "23242";

  while ((i = ssh_getopt(argc, argv, "p:h:d:D:G:t:", pgetoptdata)) != -1)
    {
      switch (i)
        {
        case 'p':
          pcontext->pport_or_service = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'h':
          pcontext->phost_name_or_address = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'd':
          pcontext->pdata = ssh_xstrdup(pgetoptdata->arg);
          break;
        case 'D':
          ssh_debug_set_module_level(SSH_DEBUG_MODULE, atoi(pgetoptdata->arg));
          break;
        case 'G':
          ssh_debug_set_global_level(atoi(pgetoptdata->arg));
          break;
        case 't':
          pcontext->timeout = atoi(pgetoptdata->arg);
          break;
        default:
          SSH_NOTREACHED;
          break;
        }
    }

  ssh_xfree(pgetoptdata);

  ssh_event_loop_initialize();

  pcontext->pbuffer = ssh_buffer_allocate();

  if (pcontext->phost_name_or_address)
    {
      ssh_tcp_connect(pcontext->phost_name_or_address,
                      pcontext->pport_or_service,
                      NULL,
                      t_tcpc_tcp_callback,
                      pcontext);
    }
  else
    {
      pcontext->ptcplistener =
        ssh_tcp_make_listener(SSH_IPADDR_ANY_IPV4,
                              pcontext->pport_or_service,
                              NULL,
                              t_tcpc_tcp_callback,
                              pcontext);
    }

  ssh_event_loop_run();
  ssh_name_server_uninit();
  ssh_event_loop_uninitialize();

  ssh_buffer_free(pcontext->pbuffer);
  ssh_xfree(pcontext);
  ssh_util_uninit();
  return 0;
}
Exemplo n.º 28
0
/* The main test program. */
int main(int argc, char *argv[])
{
  Boolean verbose = FALSE;
  SshDlList t_list;
  SshTimeMeasure ssh_timer;
  double timer_value;
  int i, k, evens, odds;

  /* Initialize the random number generator and timer */
  srand((unsigned int)ssh_time());
  ssh_timer = ssh_time_measure_allocate();

  printf("Running test for SshDlList");

  /* Check for verbose output option */
  if (argc == 2 && !strcmp("-v", argv[1]))
    {
      verbose = TRUE;
      printf(".\n\n");
    }
  else
    printf(", use -v for verbose output.\n");

  /* Initialize the test data */
  test_data = ssh_xmalloc(TEST_NUMBERS * sizeof(TestData));
  for (i=0; i < TEST_NUMBERS; i++)
    test_data[i].number = i;

  t_list = ssh_dllist_allocate();

  /* List addition tests */
  for (i=TEST_NUMBERS/2; i < TEST_NUMBERS; i++)
    if (ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_END)
        != SSH_DLLIST_OK)
      ssh_fatal("t-dllist: list addition failed. Test failed.");

  if (verbose)
    print_list(t_list);

  for (i=TEST_NUMBERS/2-1; i >= 0; i--)
    if (ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_BEGIN)
        != SSH_DLLIST_OK)
      ssh_fatal("t-dllist: list addition failed. Test failed.");

  if (verbose)
    print_list(t_list);

  /* List searching tests */
  if (verbose)
    printf("Testing list searching... ");
  ssh_dllist_rewind(t_list);

  i = 5;
  ssh_dllist_fw(t_list, i);
  if (ssh_dllist_current(t_list) != &test_data[i])
    ssh_fatal("t-dllist: problems with ssh_dllist_fw. Test failed.");

  i = 11;
  ssh_dllist_find(t_list, &test_data[i]);
  if (ssh_dllist_current(t_list) != &test_data[i])
    ssh_fatal("t-dllist: problems with ssh_dllist_find. Test failed.");

  if (verbose)
    printf("OK\n");

  /* List clear test */
  if (verbose)
    printf("Clearing the list... ");
  ssh_dllist_clear(t_list);
  if (verbose)
    printf("checking is the list empty... ");
  if (ssh_dllist_is_empty(t_list) != TRUE)
    ssh_fatal("t-dllist: list NOT empty! Test failed.\n");
  else if (verbose)
    printf("OK\n");

  /* ----------------------- performance testing ----------------------- */

  /* list addition */
  evens = odds = 0;
  ssh_time_measure_start(ssh_timer);
  for (k=0; k < ITEMS_TO_ADD_TO_THE_LIST; k++)
    {
      i = (int)((rand() / 256) % TEST_NUMBERS);

      if (i < 0 || i >= TEST_NUMBERS)
        ssh_fatal("t-dllist: random number calculation produced index out "
                  "of range.");

      if (i % 2 == 0)
        evens++;
      else
        odds++;

      ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_END);
    }
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("%d item additions took %.2f ms. Added %d evens, %d odds.\n",
           ITEMS_TO_ADD_TO_THE_LIST, timer_value * 1000, evens, odds);
  if (evens + odds != ITEMS_TO_ADD_TO_THE_LIST)
    ssh_fatal("t-dllist: evens + odds does not match. Test failed.");

  /* list length calculation */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  i = ssh_dllist_length(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("Calculating list length took %.2f ms for %d elements.\n",
           timer_value * 1000, i);
  if (i != ITEMS_TO_ADD_TO_THE_LIST)
    ssh_fatal("t-dllist: number of list elements does not match the expected. Test failed.");

  /* list reverse */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  reverse_list(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("List reverse took %.2f ms (reverse is user implemented).\n", timer_value * 1000);

  /* mapcar test */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  ssh_dllist_mapcar(t_list, remove_evens, NULL);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("Remove evens with mapcar call, it took %.2f ms, elements left: %d\n",
           timer_value * 1000,
           ssh_dllist_length(t_list));
  if (ssh_dllist_length(t_list) != odds)
    ssh_fatal("t-dllist: invalid number of list elements after mapcar. Test failed.");

  if (verbose)
    printf("Freeing everything... ");
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  ssh_dllist_free(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  ssh_xfree(test_data);
  if (verbose)
    printf("OK, took %.2f ms (list had %d items).\n", timer_value * 1000, odds);

  return 0;
}
Exemplo n.º 29
0
void signer_received_packet(SshPacketType type,
                            const unsigned char *data, size_t len,
                            void *context)
{
    /* Received. */
    unsigned int msg_byte; /* This is unsigned int because
                            SSH_FORMAT_CHAR expects uint; caused a
                            rather nasty bug during development (I
                            used SshUInt8, which wasn't long
                            enough => ssh_decode_array blew the
                            stack).*/
    char *userauth_str, *hostbased_str, *recv_pubkey_alg, *recv_hostname;
    char *recv_username;
    unsigned char *recv_pubkeyblob;
    size_t recv_pubkeyblob_len;
    /* Dug up by us. */
    char *pubkey_alg, *hostname, *username;
    unsigned char *pubkeyblob;
    size_t pubkeyblob_len;
    size_t hostname_len;

    /* Internal stuff*/
    SshSigner signer = (SshSigner) context;
    char hostkeyfile[512];
    char *comment;
    SshPrivateKey privkey;
    size_t sig_len, length_return;
    unsigned char *signature_buffer;
    SshCryptoStatus result;
    SshUser real_user;

    SSH_TRACE(2, ("Packet received."));

    switch(type)
    {
    case SSH_AUTH_HOSTBASED_PACKET:
        /* Check packet out, and if it's ok, sign it and send
           signature to ssh2. */

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(3, ("packet:"), \
                          data, len);
#endif /* HEXDUMPS */

        if (ssh_decode_array(data, len,
                             /* session id */
                             SSH_FORMAT_UINT32_STR, NULL, NULL,
                             /* SSH_MSG_USERAUTH_REQUEST (must be checked)*/
                             SSH_FORMAT_CHAR, &msg_byte,
                             /* user name */
                             SSH_FORMAT_UINT32_STR, NULL, NULL,
                             /* service "ssh-userauth" (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &userauth_str, NULL,
                             /* "hostbased" (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &hostbased_str, NULL,
                             /* public key algorithm for hostkey (must
                                be checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_pubkey_alg, NULL,
                             /* public hostkey and certificates (must be
                                checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_pubkeyblob,
                             &recv_pubkeyblob_len,
                             /* client host name (must be checked)*/
                             SSH_FORMAT_UINT32_STR, &recv_hostname, NULL,
                             /* user name on client host (must be checked) */
                             SSH_FORMAT_UINT32_STR, &recv_username, NULL,
                             SSH_FORMAT_END) != len || len == 0)
        {
            /* There was an error. */
            SSH_TRACE(0, ("Invalid packet."));
            goto error;
        }

        /* Get pubkeyblob, pubkeyblob_len, pubkey_alg, hostname and
           username. */

        /* Dig up hosts publickey. */
        if(signer->config->public_host_key_file[0] != '/')
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                     signer->config->public_host_key_file);
        }
        else
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                     signer->config->public_host_key_file);
        }

        SSH_TRACE(2, ("place to look for public key: %s", hostkeyfile));

        /* This pubkey*-stuff is for the client _host's_ public
           hostkey. */
        /* Getting pubkeyblob, pubkeyblob_len */
        SSH_DEBUG(4, ("Reading pubkey-blob from %s...", hostkeyfile));
        if (ssh2_key_blob_read(signer->effective_user_data, hostkeyfile, NULL,
                               &pubkeyblob,
                               &pubkeyblob_len, NULL)
                != SSH_KEY_MAGIC_PUBLIC)
        {
            SSH_TRACE(1, ("Reading public key failed."));
            goto error;
        }

        SSH_DEBUG(4, ("done."));

        if ((pubkey_alg =
                    ssh_pubkeyblob_type(pubkeyblob, pubkeyblob_len))
                == NULL)
        {
            SSH_TRACE(1, ("Couldn't figure out public key algorithm."));
            goto error;
        }

        /* Getting hostname. */
        hostname = ssh_xmalloc(MAXHOSTNAMELEN + 1);
        ssh_tcp_get_host_name(hostname, MAXHOSTNAMELEN + 1);
        hostname_len = strlen(hostname);
        /* Sanity check */
        SSH_ASSERT(hostname_len + 2 < MAXHOSTNAMELEN);
        /* We want FQDN. */
        hostname[hostname_len] = '.';
        hostname[hostname_len + 1] = '\0';

        /* Getting username. */
        real_user = ssh_user_initialize(NULL, FALSE);
        username = ssh_xstrdup(ssh_user_name(real_user));
        ssh_user_free(real_user, FALSE);

        /* Check all parameters. */
        if (msg_byte != SSH_MSG_USERAUTH_REQUEST)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("msg_byte != SSH_MSG_USERAUTH_REQUEST " \
                          "(msg_byte = %d)", msg_byte));
            goto error;
        }
        if (strcmp(userauth_str, SSH_USERAUTH_SERVICE) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("userauth_str != \"ssh-userauth\" (it was '%s')", \
                          userauth_str));
            goto error;
        }
        if (strcmp(hostbased_str, SSH_AUTH_HOSTBASED) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("hostbased_str != \"hostbased\" (it was '%s')", \
                          hostbased_str));
            goto error;
        }
        /* XXX has to be change when adding support for multiple hostkeys */
        if (strcmp(recv_pubkey_alg, pubkey_alg) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client gave us invalid pubkey-algorithms for our " \
                          "hostkey."));
            goto error;
        }

        if (recv_pubkeyblob_len == pubkeyblob_len)
        {
            if (memcmp(recv_pubkeyblob, pubkeyblob, pubkeyblob_len) != 0)
            {
                SSH_TRACE(1, ("Invalid packet."));
                SSH_DEBUG(1, ("client gave us wrong (or corrupted) " \
                              "public key."));
#ifdef HEXDUMPS
                SSH_DEBUG_HEXDUMP(3, ("client gave us:"), \
                                  recv_pubkeyblob, pubkeyblob_len);
                SSH_DEBUG_HEXDUMP(3, ("our pubkey:"), \
                                  recv_pubkeyblob, pubkeyblob_len);
#endif /* HEXDUMPS */
                goto error;
            }
        }
        else
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client gave us wrong (or corrupted) public key. " \
                          "Lengths differ (received: %d ; ours: %d)", \
                          recv_pubkeyblob_len, pubkeyblob_len));
            goto error;
        }

        if (strcmp(recv_hostname, hostname) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Wethinks the client gave us the wrong hostname. " \
                          "(client's opinion: '%s' ours: '%s'", \
                          recv_hostname, hostname));
            goto error;
        }
        if (strcmp(recv_username, username) != 0)
        {
            SSH_TRACE(1, ("Invalid packet."));
            SSH_DEBUG(1, ("Client definitely gave us the wrong user name. " \
                          "(it says: '%s' we know: '%s')", recv_username, \
                          username));
            goto error;
        }

        /* Sign the packet and send it to client. */

        /* If we've gotten this far, the packet is ok, and it can be
           signed. */

        SSH_TRACE(0, ("Received packet ok."));
        if(signer->config->public_host_key_file[0] != '/')
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s/%s", SSH_SERVER_DIR,
                     signer->config->host_key_file);
        }
        else
        {
            snprintf(hostkeyfile, sizeof(hostkeyfile), "%s",
                     signer->config->host_key_file);
        }

        SSH_TRACE(2, ("place to look for private key: %s", hostkeyfile));

        if ((privkey = ssh_privkey_read(signer->effective_user_data, hostkeyfile, "",
                                        &comment, NULL)) == NULL)
            ssh_fatal("ssh_privkey_read from %s failed.", hostkeyfile);

        /* Check how big a chunk our private key can sign (this is
           purely a sanity check, as both of our signature schemas do
           their own hashing) */
        sig_len = ssh_private_key_max_signature_input_len(privkey);

        SSH_TRACE(2, ("max input length for signing: %d", sig_len));

        if (sig_len == 0)
        {
            SSH_TRACE(0, ("private key not capable of signing! " \
                          "(definitely an error)"));
            goto error;
        }
        else if (sig_len != -1 && sig_len < len)
        {
            SSH_TRACE(0, ("private key can't sign our data. (too much " \
                          "data (data_len %d, max input len for signing " \
                          "%d))", len, sig_len));
            goto error;
        }

        /* Now check how much we much buffer we must allocate for the
           signature. */
        sig_len = ssh_private_key_max_signature_output_len(privkey);

        SSH_TRACE(2, ("max output length for signature: %d", sig_len));

        signature_buffer = ssh_xcalloc(sig_len, sizeof(unsigned char));

        /* Do the actual signing. */

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(5, ("Signing following data"),
                          data + 4, len - 4);
#endif /* HEXDUMPS */

        if ((result = ssh_private_key_sign(privkey,
                                           data,
                                           len,
                                           signature_buffer,
                                           sig_len,
                                           &length_return,
                                           signer->random_state))
                != SSH_CRYPTO_OK)
        {
            SSH_TRACE(0, ("ssh_private_key_sign() returned %d.", result));
            goto error;
        }

#ifdef HEXDUMPS
        SSH_DEBUG_HEXDUMP(5, ("Signature"), signature_buffer, length_return);
#endif /* HEXDUMPS */
        /* Send it to client. */
        signer->packet_payload = signature_buffer;
        signer->packet_payload_len = length_return;
        signer->packet_waiting = TRUE;

        if (ssh_packet_wrapper_can_send(signer->wrapper))
            signer_can_send(signer);

        /* XXX free dynamically allocated data. */
        ssh_xfree(username);

        break;
    case SSH_AUTH_HOSTBASED_SIGNATURE:
        /* We shouldn't get this type of packet. This is an error.*/
        SSH_TRACE(0, ("client sent us SSH_AUTH_HOSTBASED_SIGNATURE. This " \
                      "is an error."));
        goto error;
        break;
    case SSH_AUTH_HOSTBASED_ERROR:
        /* We shouldn't be getting this either. This is an error. */
        SSH_TRACE(0, ("client sent us SSH_AUTH_HOSTBASED_SIGNATURE_ERROR. " \
                      "This is an error. (This message can be sent by " \
                      "ssh-signer2 only)"));
        goto error;
        break;
    }
    return;

    /* We come here after errors. */
error:
    /* Send error message to ssh2, and wait for ssh2 to send
       EOF. */
    ssh_packet_wrapper_send_encode(signer->wrapper, SSH_AUTH_HOSTBASED_ERROR,
                                   SSH_FORMAT_END);

    /* Init a 5 second timeout. If ssh2 hasn't disconnected at
       that time, close stream.*/
    ssh_register_timeout(5L, 0L, signer_destroy_timeout, signer);

    return;
}
Exemplo n.º 30
0
void *ssh_xrealloc(void *ptr, unsigned long new_size)
{
  void *new_ptr;

  if (ptr == NULL)
    return ssh_xmalloc(new_size);

  if (new_size > XMALLOC_MAX_SIZE)
    ssh_fatal("ssh_xrealloc: allocation too large (allocating %ld bytes)",
              (long)new_size);
  
  if (new_size == 0)
    new_size = 1;
#ifdef SSH_DEBUG_MALLOC
  if (SSH_GET_32BIT((unsigned char *) ptr - 4) !=
      SSH_DEBUG_MALLOC_MAGIC_IN_USE)
    {
      if (SSH_GET_32BIT((unsigned char *) ptr - 4) ==
          SSH_DEBUG_MALLOC_MAGIC_FREED)
        ssh_fatal("Reallocating block that is already freed");
      ssh_fatal("Reallocating block that is either not mallocated, or whose magic number before the object was overwritten");
    }
  else
    {
      unsigned long old_size;

      old_size = SSH_GET_32BIT((unsigned char *) ptr -
                               SSH_DEBUG_MALLOC_SIZE_BEFORE);
      if (SSH_GET_32BIT((unsigned char *) ptr + old_size) !=
          SSH_DEBUG_MALLOC_MAGIC_AFTER)
        ssh_fatal("Reallocating block whose magic number after the object was overwritten");

      /* Mark the old block freed */
      SSH_PUT_32BIT((unsigned char *) ptr - 4, SSH_DEBUG_MALLOC_MAGIC_FREED);
      SSH_PUT_32BIT((unsigned char *) ptr + old_size,
                    SSH_DEBUG_MALLOC_MAGIC_FREED);

      new_ptr = (void *)realloc((unsigned char *) ptr -
                                SSH_DEBUG_MALLOC_SIZE_BEFORE,
                                (size_t) new_size +
                                SSH_DEBUG_MALLOC_SIZE_BEFORE +
                                SSH_DEBUG_MALLOC_SIZE_AFTER);
      if (new_ptr == NULL)
        ssh_fatal("ssh_xrealloc: out of memory (new_size %ld bytes)",
                  (long)new_size);

      SSH_PUT_32BIT(new_ptr, new_size);
      SSH_PUT_32BIT((unsigned char *) new_ptr + 4,
                    SSH_DEBUG_MALLOC_MAGIC_IN_USE);
      SSH_PUT_32BIT((unsigned char *) new_ptr + new_size +
                    SSH_DEBUG_MALLOC_SIZE_BEFORE,
                    SSH_DEBUG_MALLOC_MAGIC_AFTER);
      new_ptr = (unsigned char *) new_ptr + SSH_DEBUG_MALLOC_SIZE_BEFORE;
    }
#else /* SSH_DEBUG_MALLOC */
  new_ptr = (void *)realloc(ptr, (size_t) new_size);
  if (new_ptr == NULL)
    ssh_fatal("ssh_xrealloc: out of memory (new_size %ld bytes)",
              (long)new_size);
#endif /* SSH_DEBUG_MALLOC */
  return new_ptr;
}