コード例 #1
0
ファイル: session.c プロジェクト: caidongyun/libssh
/**
 * @brief Create a new ssh session.
 *
 * @returns             A new ssh_session pointer, NULL on error.
 */
ssh_session ssh_new(void) {
  ssh_session session;
  char *id = NULL;
  int rc;

  session = malloc(sizeof (struct ssh_session_struct));
  if (session == NULL) {
    return NULL;
  }
  ZERO_STRUCTP(session);

  session->next_crypto = crypto_new();
  if (session->next_crypto == NULL) {
    goto err;
  }

  session->socket = ssh_socket_new(session);
  if (session->socket == NULL) {
    goto err;
  }

  session->out_buffer = ssh_buffer_new();
  if (session->out_buffer == NULL) {
    goto err;
  }

  session->in_buffer=ssh_buffer_new();
  if (session->in_buffer == NULL) {
    goto err;
  }

  session->alive = 0;
  session->auth_methods = 0;
  ssh_set_blocking(session, 1);
  session->maxchannel = FIRST_CHANNEL;

#ifndef _WIN32
    session->agent = ssh_agent_new(session);
    if (session->agent == NULL) {
      goto err;
    }
#endif /* _WIN32 */

    /* OPTIONS */
    session->opts.StrictHostKeyChecking = 1;
    session->opts.port = 0;
    session->opts.fd = -1;
    session->opts.ssh2 = 1;
    session->opts.compressionlevel=7;
#ifdef WITH_SSH1
    session->opts.ssh1 = 1;
#else
    session->opts.ssh1 = 0;
#endif

    session->opts.identity = ssh_list_new();
    if (session->opts.identity == NULL) {
      goto err;
    }

#ifdef HAVE_ECC
    id = strdup("%d/id_ecdsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }
#endif

    id = strdup("%d/id_rsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    id = strdup("%d/id_dsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    id = strdup("%d/identity");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    return session;

err:
    free(id);
    ssh_free(session);
    return NULL;
}
コード例 #2
0
ファイル: torture.c プロジェクト: MachalkA/libssh
ssh_session torture_ssh_session(const char *host,
                                const char *user,
                                const char *password) {
    ssh_session session;
    int rc;

    if (host == NULL) {
        return NULL;
    }

    session = ssh_new();
    if (session == NULL) {
        return NULL;
    }

    if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
        goto failed;
    }

    if (user != NULL) {
        if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
            goto failed;
        }
    }

    if (ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity) < 0) {
        goto failed;
    }

    if (ssh_connect(session)) {
        goto failed;
    }

    /* We are in testing mode, so consinder the hostkey as verified ;) */

    /* This request should return a SSH_REQUEST_DENIED error */
    rc = ssh_userauth_none(session, NULL);
    if (rc == SSH_ERROR) {
        goto failed;
    }
    if (!(ssh_auth_list(session) & SSH_AUTH_METHOD_INTERACTIVE)) {
        goto failed;
    }

    if (password != NULL) {
        rc = _torture_auth_kbdint(session, password);
    } else {
        rc = ssh_userauth_autopubkey(session, NULL);
        if (rc == SSH_AUTH_ERROR) {
            goto failed;
        }
    }
    if (rc != SSH_AUTH_SUCCESS) {
        goto failed;
    }

    return session;
failed:
    if (ssh_is_connected(session)) {
        ssh_disconnect(session);
    }
    ssh_free(session);

    return NULL;
}
コード例 #3
0
ファイル: sshdump.c プロジェクト: chuanher/wireshark
static ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username,
	const char* password, const char* sshkey_path, const char* sshkey_passphrase)
{
	ssh_session sshs;

	/* Open session and set options */
	sshs = ssh_new();
	if (sshs == NULL) {
		errmsg_print("Can't create ssh session");
		return NULL;
	}

	if (!hostname)
		return NULL;

	if (ssh_options_set(sshs, SSH_OPTIONS_HOST, hostname)) {
		errmsg_print("Can't set the hostname: %s\n", hostname);
		goto failure;
	}

	if (port != 0) {
		if (ssh_options_set(sshs, SSH_OPTIONS_PORT, &port)) {
			errmsg_print("Can't set the port: %d\n", port);
			goto failure;
		}
	}

	if (!username)
		username = g_get_user_name();

	if (ssh_options_set(sshs, SSH_OPTIONS_USER, username)) {
		errmsg_print("Can't set the username: %s\n", username);
		goto failure;
	}

	verbose_print("Opening ssh connection to %s@%s:%u\n", username, hostname, port);

	/* Connect to server */
	if (ssh_connect(sshs) != SSH_OK) {
		errmsg_print("Error connecting to %s@%s:%u (%s)\n", username, hostname, port,
			ssh_get_error(sshs));
		goto failure;
	}

#ifdef HAVE_LIBSSH_USERAUTH_AGENT
	verbose_print("Connecting using ssh-agent...");
	/* Try to authenticate using ssh agent */
	if (ssh_userauth_agent(sshs, NULL) == SSH_AUTH_SUCCESS) {
		verbose_print("done\n");
		return sshs;
	}
	verbose_print("failed\n");
#endif

	/* If a public key path has been provided, try to authenticate using it */
	if (sshkey_path) {
		ssh_key pkey = ssh_key_new();
		int ret;

		verbose_print("Connecting using public key in %s...", sshkey_path);
		ret = ssh_pki_import_privkey_file(sshkey_path, sshkey_passphrase, NULL, NULL, &pkey);

		if (ret == SSH_OK) {
			if (ssh_userauth_publickey(sshs, NULL, pkey) == SSH_AUTH_SUCCESS) {
				verbose_print("done\n");
				ssh_key_free(pkey);
				return sshs;
			}
		}
		ssh_key_free(pkey);
		verbose_print("failed (%s)\n", ssh_get_error(sshs));
	}

	/* Try to authenticate using standard public key */
	verbose_print("Connecting using standard public key...");
	if (ssh_userauth_publickey_auto(sshs, NULL, NULL) == SSH_AUTH_SUCCESS) {
		verbose_print("done\n");
		return sshs;
	}
	verbose_print("failed\n");

	/* If a password has been provided and all previous attempts failed, try to use it */
	if (password) {
		verbose_print("Connecting using password...");
		if (ssh_userauth_password(sshs, username, password) == SSH_AUTH_SUCCESS) {
			verbose_print("done\n");
			return sshs;
		}
		verbose_print("failed\n");
	}

	errmsg_print("Can't find a valid authentication. Disconnecting.\n");

	/* All authentication failed. Disconnect and return */
	ssh_disconnect(sshs);

failure:
	ssh_free(sshs);
	return NULL;
}
コード例 #4
0
ファイル: sshsocks.c プロジェクト: patrick-ken/kernel_808l
/*
 * Parse incoming socks connection from buffer. Consume the request
 * packet data from buffer. If everything is ok it allocates SocksInfo
 * strcture and store the request fields in it (sets
 * socks_version_number, command_code, ip, port, username). Returns
 * SSH_SOCKS_SUCCESS, SSH_SOCKS_TRY_AGAIN, or SSH_SOCKS_ERROR_*. If
 * anything other than SSH_SOCKS_SUCCESS is returned the socksinfo is
 * set to NULL.  Use ssh_socks_free to free socksinfo data.
 */
SocksError ssh_socks_server_parse_open(SshBuffer buffer, SocksInfo *socksinfo)
{
  unsigned char *data, *ip;
  unsigned long i, port;
  unsigned int version, cmd, ip_addr_len, atyp;
  unsigned char *username = NULL;
  size_t ret, len, bytes = 0;

  *socksinfo = NULL;
  len = ssh_buffer_len(buffer);
  data = ssh_buffer_ptr(buffer);

  if (len < 1)
    return SSH_SOCKS_TRY_AGAIN;

  version = data[0];
  bytes++;

  if (version != 4 && version != 5)
    {
      SSH_DEBUG(2, ("Server gave us version %d.", version));
      return SSH_SOCKS_ERROR_UNSUPPORTED_SOCKS_VERSION;
    }

  if (version == 4)
    {
      /* Check if enough data for header and name */
      if (len < SOCKS4_COMMAND_SIZE + 1)
        {
          return SSH_SOCKS_TRY_AGAIN;
        }


      /* Find the end of username */
      for (i = SOCKS4_COMMAND_SIZE; i < len; i++)
        {
          if (data[i] == '\0')
            break;
        }

      /* End of username not found, return either error or try_again */
      if (i == len || data[i] != '\0')
        {
          if (len > SOCKS4_COMMAND_SIZE + SOCKS4_MAX_NAME_LEN)
            {
              return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
            }
          return SSH_SOCKS_TRY_AGAIN;
        }

      cmd = data[1];

      port = SSH_GET_16BIT(&data[2]);

      ip_addr_len = 4;
      ip = ssh_memdup(&data[4], ip_addr_len);
      atyp = SSH_SOCKS5_ATYP_IPV4;

      if (ip == NULL)
        {
          SSH_DEBUG(2, ("Failed to allocate IP-address buffer."));
          return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
        }

      username = ssh_strdup((char *)(data + SOCKS4_COMMAND_SIZE));
      bytes = SOCKS4_COMMAND_SIZE +
        strlen((char *) data + SOCKS4_COMMAND_SIZE) + 1;
    }
  else
    {
      unsigned char port_buf[2];

      if (len - bytes < 3)
        return SSH_SOCKS_TRY_AGAIN;

      ret = ssh_decode_array(data + bytes, len - bytes,
                             SSH_DECODE_CHAR(&cmd),
                             SSH_DECODE_CHAR(NULL), /* RSV */
                             SSH_DECODE_CHAR(&atyp),
                             SSH_FORMAT_END);
      if (ret <= 0)
        {
          SSH_DEBUG(2, ("Failed to decode command packet."));
          return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
        }
      bytes += ret;
      if (atyp == SSH_SOCKS5_ATYP_IPV4)
        {
          SSH_DEBUG(4, ("SOCKS5 received address type IPV4."));
          ip_addr_len = 4;
        }
      else if (atyp == SSH_SOCKS5_ATYP_IPV6)
        {
          SSH_DEBUG(4, ("SOCKS5 received address type IPV6."));
          ip_addr_len = 16;
        }
      else if (atyp == SSH_SOCKS5_ATYP_FQDN)
        {
          if (len - bytes < 1)
            return SSH_SOCKS_TRY_AGAIN;

          ip_addr_len = *(data + bytes);
          if (ip_addr_len <= 0 || ip_addr_len >= 255)
            {
              SSH_DEBUG(2, ("Invalid FQDN address len %d.", ip_addr_len));
              return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
            }
          SSH_DEBUG(4, ("SOCKS5 received address type FQDN, len %d.",
                        ip_addr_len));
          bytes++;
        }
      else
        {
          SSH_DEBUG(2, ("Invalid address type %d.", atyp));
          return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
        }
      /* ip addr len + port */
      if (len - bytes < ip_addr_len + 2)
        return SSH_SOCKS_TRY_AGAIN;

      ip = ssh_calloc(ip_addr_len + 1, sizeof(unsigned char));
      if (ip == NULL)
        {
          SSH_DEBUG(2, ("Failed to allocate IP-address buffer."));
          return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
        }
      ret = ssh_decode_array(data + bytes, len - bytes,
                             SSH_DECODE_DATA(ip, ip_addr_len),
                             SSH_DECODE_DATA(port_buf, 2),
                             SSH_FORMAT_END);
      if (ret <= 0)
        {
          SSH_DEBUG(2, ("Failed to decode command packet."));
          ssh_free(ip);
          return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
        }
      port = SSH_GET_16BIT(port_buf);
      bytes += ret;
    }

  if ((*socksinfo = ssh_calloc(1, sizeof(struct SocksInfoRec))) == NULL)
    {
      SSH_DEBUG(2, ("Failed to allocate SocksInfo."));
      ssh_free(ip);
      return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
    }

  if (atyp == SSH_SOCKS5_ATYP_FQDN)
    {
      (*socksinfo)->ip = ip;
    }
  else
    {
      SshIpAddrStruct ip_addr;
      unsigned char buf[SSH_IP_ADDR_STRING_SIZE];

      SSH_IP_DECODE(&ip_addr, ip, ip_addr_len);

      ssh_ipaddr_print(&ip_addr, buf, sizeof(buf));
      (*socksinfo)->ip = ssh_memdup(buf, ssh_ustrlen(buf));
      ssh_free(ip);
      if ((*socksinfo)->ip == NULL)
        {
          SSH_DEBUG(2, ("Failed to allocate final IP-addr buf."));
          return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
        }
    }

  (*socksinfo)->socks_version_number = version;
  (*socksinfo)->command_code = cmd;
  ssh_dsprintf(&(*socksinfo)->port, "%lu", port);
  (*socksinfo)->username = username;
  ssh_buffer_consume(buffer, bytes);
  SSH_DEBUG(5, ("Decoded %zd bytes.", bytes));
  return SSH_SOCKS_SUCCESS;
}
コード例 #5
0
SshEapToken
ssh_eap_dup_token(SshEapToken src)
{
  SshEapToken dst;

  dst = ssh_calloc(1, sizeof(*dst));

  if (dst == NULL)
    return NULL;

  dst->type = src->type;

  switch (src->type)
    {



















    case SSH_EAP_TOKEN_PRIVATE_KEY:
   if (src->token.prvkey.private_key != NULL)
     {
       if (ssh_private_key_copy(src->token.prvkey.private_key, 
				&dst->token.prvkey.private_key) 
	   != SSH_CRYPTO_OK)
	 {
	   ssh_free(dst);
	   return NULL;
	 }
       if (src->token.prvkey.id_data != NULL)
         {
           dst->token.prvkey.id_data 
             = ssh_memdup(src->token.prvkey.id_data,
                          src->token.prvkey.id_data_size);
           if (dst->token.prvkey.id_data == NULL)
             {
               ssh_private_key_free(dst->token.prvkey.private_key);
               ssh_free(dst);
               return NULL;
             }
           dst->token.prvkey.id_data_size = src->token.prvkey.id_data_size;
         }
     }
   break;

    case SSH_EAP_TOKEN_CERTIFICATE_AUTHORITY:
      {
        int cnt;
        int i;

        /* Count the ca count. */
        for (cnt = 0; src->token.cas && src->token.cas[cnt]; cnt++)
          ;

        if (cnt == 0)
          {
            SSH_DEBUG(SSH_D_ERROR, ("Cannot duplicate token, no"
                                    " CA's to duplicate."));
            ssh_free(dst);
            return NULL;
          }

        dst->token.cas = ssh_calloc(cnt + 1, sizeof(unsigned char *));
        if (dst->token.cas == NULL)
          {
            ssh_free(dst);
            return NULL;
          }

        for (i = 0; i < cnt; i++)
          dst->token.cas[i] = src->token.cas[i];

        break;
      }

#ifdef SSHDIST_EAP_SIM
    case SSH_EAP_TOKEN_SIM_CHALLENGE:
#endif /* SSHDIST_EAP_SIM */
#ifdef SSHDIST_EAP_AKA
    case SSH_EAP_TOKEN_AKA_CHALLENGE:
    case SSH_EAP_TOKEN_AKA_SYNCH_REQ:
#endif /* SSHDIST_EAP_AKA */
    case SSH_EAP_TOKEN_USERNAME:
    case SSH_EAP_TOKEN_SHARED_SECRET:
    case SSH_EAP_TOKEN_SALT:

      if (src->token.buffer.dptr != NULL)
        {
          dst->token.buffer.dptr = ssh_malloc(src->token.buffer.len);
          if (dst->token.buffer.dptr == NULL)
            {
              ssh_free(dst);
              return NULL;
            }
	  
          dst->token.buffer.len = src->token.buffer.len;
          memcpy(dst->token.buffer.dptr, src->token.buffer.dptr,
                 src->token.buffer.len);
        }
      else
        {
          dst->token.buffer.dptr = NULL;
          dst->token.buffer.len = 0;
        }
      break;
    case SSH_EAP_TOKEN_COUNTER32:
      dst->token.counter32 = src->token.counter32;
      break;
      
#ifdef SSHDIST_EAP_AKA_DASH
    case SSH_EAP_TOKEN_AKA_DASH_KDF_INPUT:
      dst->token.success = src->token.success;
      break;
#endif /* SSHDIST_EAP_AKA_DASH */

#ifdef SSHDIST_EAP_AKA
    case SSH_EAP_TOKEN_AKA_AUTH_REJECT:
#endif /* SSHDIST_EAP_AKA */
    case SSH_EAP_TOKEN_NONE:
      break;
    default:
      SSH_NOTREACHED;
    }

  SSH_DEBUG(SSH_D_MY, ("duplicated token at %p", dst));

  return dst;
}
コード例 #6
0
/* Import given buffer to the IKE Server given in the argument. Returns the IKE
   SA negotiation or NULL in case of error. The data that was parsed
   successfully is consumed from the buffer in any case. If there is extra data
   after the complete packet then it is left to the buffer. */
SshIkeNegotiation ssh_ike_sa_import(SshBuffer buffer,
                                    SshIkeServerContext server)
{
  unsigned char initiator_cookie[SSH_IKE_COOKIE_LENGTH];
  unsigned char responder_cookie[SSH_IKE_COOKIE_LENGTH];
  unsigned char *auc, *buc, *cuc, *duc;
  SshUInt32 a32, b32, c32, d32;
  SshUInt64 a64, b64, c64, d64;
  SshIkePMPhaseI pm_info;
  SshIkeNegotiation neg;
  SshIkeSA sa;
  size_t len;
  long l;
  SshADTHandle h;
  SshCryptoStatus cret;
  SshTime t;
  SshUInt16 local_port;

  sa = NULL;
  pm_info = NULL;
  neg = NULL;
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  SSH_DEBUG(5, ("Start"));

  len = ssh_decode_buffer
    (buffer,
     /* Magic number */
     SSH_DECODE_UINT32(&a32),
     /* Version number */
     SSH_DECODE_UINT32(&b32),
     /* Cookies, initiator, responder */
     SSH_DECODE_DATA(initiator_cookie, SSH_IKE_COOKIE_LENGTH),
     SSH_DECODE_DATA(responder_cookie, SSH_IKE_COOKIE_LENGTH),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode magic, version, cookies"));
      goto error;
    }
  if (a32 != SSH_IKE_EXPORT_MAGIC1)
    {
      SSH_DEBUG(3, ("Invalid magic 0x%08x vs 0x%08x", (int) a32,
                    SSH_IKE_EXPORT_MAGIC1));
      goto error;
    }
  if (b32 != SSH_IKE_EXPORT_VERSION)
    {
      SSH_DEBUG(3, ("Invalid version 0x%08x vs 0x%08x", (int) b32,
                    SSH_IKE_EXPORT_VERSION));
      goto error;
    }

  h = ssh_adt_get_handle_to_equal(server->isakmp_context->
                                  isakmp_cookie_mapping, initiator_cookie);
  if (h != SSH_ADT_INVALID)
    {
      SSH_DEBUG(3, ("Duplicate initiator cookie"));
      goto error;
    }

  sa = ike_sa_allocate(server, initiator_cookie, responder_cookie);
  if (sa == NULL)
    {
      SSH_DEBUG(3, ("ike_sa_allocate_half return error"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Local ip, port. */
     SSH_DECODE_UINT32_STR(&auc, NULL),
     SSH_DECODE_UINT32_STR(&buc, NULL),
     /* Remote ip, port. */
     SSH_DECODE_UINT32_STR(&cuc, NULL),
     SSH_DECODE_UINT32_STR(&duc, NULL),
     /* IKE exchange version. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),
     /* IKE exchange type. */
     SSH_DECODE_UINT32(&c32),
     /* Was this the initiator for the original exchange? */
     SSH_DECODE_UINT32(&d32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode ip, port, version, exchage type, init"));
      goto error;
    }
  if (!ike_init_isakmp_sa(sa, auc, buc, cuc, duc, a32, b32, c32, d32, FALSE))
    {
      SSH_DEBUG(3, ("Could not init isakmp sa"));
      goto error;
    }
  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  neg = sa->isakmp_negotiation;
  pm_info = neg->ike_pm_info;

  /* Initialize */
  sa->phase_1_done = 1;
  neg->notification_state = SSH_IKE_NOTIFICATION_STATE_ALREADY_SENT;
  ike_free_negotiation_isakmp(neg);


  /* Set NAT-T status. */
  local_port = ssh_uatoi(sa->isakmp_negotiation->ike_pm_info->local_port);
  if (local_port != server->normal_local_port)
    sa->use_natt = 1;

  /* I think we should count this as SA */
  server->statistics->current_ike_sas++;
  server->statistics->total_ike_sas++;
  if (neg->ike_pm_info->this_end_is_initiator)
    {
      server->statistics->current_ike_sas_initiated++;
      server->statistics->total_ike_sas_initiated++;
    }
  else
    {
      server->statistics->current_ike_sas_responded++;
      server->statistics->total_ike_sas_responded++;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Byte count and byte limit. */
     SSH_DECODE_UINT64(&a64),
     SSH_DECODE_UINT64(&b64),
     /* Created time and laste use time */
     SSH_DECODE_UINT64(&c64),
     SSH_DECODE_UINT64(&d64),
     /* Encryption, hash, prf algorithm names. */
     SSH_DECODE_UINT32_STR(&auc, NULL),
     SSH_DECODE_UINT32_STR(&buc, NULL),
     SSH_DECODE_UINT32_STR(&cuc, NULL),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode byte count limit, times, alg names"));
      goto error;
    }
  sa->byte_count = (unsigned long) a64;
  sa->kbyte_limit = (unsigned long) b64;
  sa->created_time = (SshTime) c64;
  sa->last_use_time = (SshTime) d64;

  l = ssh_find_keyword_number(ssh_ike_encryption_algorithms, ssh_csstr(auc));
  if (l == -1)
    {
      if (ssh_usstrcmp(auc, "cast128-12-cbc") == 0)
        sa->encryption_algorithm_name = ssh_custr("cast128-12-cbc");
      else
        {
          SSH_DEBUG(3, ("Unknown cipher %s", auc));
          goto error;
        }
    }
  else
    {
      sa->encryption_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_encryption_algorithms, l));
      SSH_ASSERT(sa->encryption_algorithm_name != NULL);
    }

  l = ssh_find_keyword_number(ssh_ike_hash_algorithms, ssh_csstr(buc));
  if (l == -1)
    {
      SSH_DEBUG(3, ("Unknown hash %s", buc));
      goto error;
    }
  else
    {
      sa->hash_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_hash_algorithms, l));
      SSH_ASSERT(sa->hash_algorithm_name != NULL);
    }

  l = ssh_find_keyword_number(ssh_ike_hmac_prf_algorithms, ssh_csstr(cuc));
  if (l == -1)
    {
      SSH_DEBUG(3, ("Unknown prf %s", cuc));
      goto error;
    }
  else
    {
      sa->prf_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_hmac_prf_algorithms, l));
      SSH_ASSERT(sa->prf_algorithm_name != NULL);
    }

  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  len = ssh_decode_buffer
    (buffer,
     /* Cipher key. */
     SSH_DECODE_UINT32_STR(&sa->cipher_key, &sa->cipher_key_len),
     /* Cipher IV. */
     SSH_DECODE_UINT32_STR(&sa->cipher_iv, &sa->cipher_iv_len),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode cipher key, iv"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Keying material, Diffie-Hellman. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.dh, &sa->skeyid.dh_size),
     /* Keying material, SKEYID mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid, &sa->skeyid.skeyid_size),
     /* Keying material, SKEYID_d mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_d, &sa->skeyid.skeyid_d_size),
     /* Keying material, SKEYID_a mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_a, &sa->skeyid.skeyid_a_size),
     /* Keying material, SKEYID_e mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_e, &sa->skeyid.skeyid_e_size),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode skeyid"));
      goto error;
    }
  sa->skeyid.initialized = TRUE;

  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid,
                          sa->skeyid.skeyid_size,
                          &sa->skeyid.skeyid_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }

  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid_a,
                          sa->skeyid.skeyid_a_size,
                          &sa->skeyid.skeyid_a_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }
  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid_e,
                          sa->skeyid.skeyid_e_size,
                          &sa->skeyid.skeyid_e_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Retry defaults. */
     SSH_DECODE_UINT32(&sa->retry_limit),
     SSH_DECODE_UINT32(&sa->retry_timer),
     SSH_DECODE_UINT32(&sa->retry_timer_usec),
     SSH_DECODE_UINT32(&sa->retry_timer_max),
     SSH_DECODE_UINT32(&sa->retry_timer_max_usec),
     SSH_DECODE_UINT32(&sa->expire_timer),
     SSH_DECODE_UINT32(&sa->expire_timer_usec),
     /* Statistics. */
     SSH_DECODE_UINT32(&sa->statistics.packets_in),
     SSH_DECODE_UINT32(&sa->statistics.packets_out),
     SSH_DECODE_UINT32(&sa->statistics.octects_in),
     SSH_DECODE_UINT32(&sa->statistics.octects_out),
     SSH_DECODE_UINT32(&sa->statistics.created_suites),
     SSH_DECODE_UINT32(&sa->statistics.deleted_suites),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode retry, expire timers and stats"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* IKE SA negotiation information. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),





     SSH_DECODE_UINT32(&c32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode ike sa info and private group cnt"));
      goto error;
    }
  neg->exchange_type = a32;
  /* The b32 used to be authe_method_type, but as it was duplicate for the
     value in pm_info, we ignore it now. */
  if (c32 != 0)
    {
      ssh_warning("Remote end sent packet including private groups. "
                  "This end does not support transferring of them. "
                  "Private groups ignored");
    }
  len = ssh_decode_buffer
    (buffer,
     /* Private groups as UINT32_STRING. */ 



     SSH_DECODE_UINT32_STR(NULL, NULL),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode private groups info"));
      goto error;
    }

  if (!ssh_ike_sa_import_id(buffer, &pm_info->local_id,
                            &pm_info->local_id_txt))
    {
      SSH_DEBUG(3, ("Could not decode local id"));
      goto error;
    }
  if (!ssh_ike_sa_import_id(buffer, &pm_info->remote_id,
                            &pm_info->remote_id_txt))
    {
      SSH_DEBUG(3, ("Could not decode remote id"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Authentication type. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),
     /* Start and expire times. */
     SSH_DECODE_UINT64(&a64),
     SSH_DECODE_UINT64(&b64),
     /* None of the policy manager filled data is copied, this include
        auth_data, auth_data_len, own_auth_data, own_auth_data_len,
        public_key, number_of_certificates, number_of_allocated_certificates,
        certificates, certificate_lens, certificate_encodings,
        policy_manager_data, pm. */
     SSH_DECODE_UINT32(&c32),
     /* Magic number */
     SSH_DECODE_UINT32(&d32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode pm info and magic2"));
      goto error;
    }
  pm_info->auth_method_type = a32;
  pm_info->auth_method = b32;
  pm_info->sa_start_time = (SshTime) a64;
  pm_info->sa_expire_time = (SshTime) b64;
  pm_info->doi = c32;
  if (d32 != SSH_IKE_EXPORT_MAGIC2)
    {
      SSH_DEBUG(3, ("Invalid magic2 0x%08x vs 0x%08x", (int) d32,
                    SSH_IKE_EXPORT_MAGIC2));
      goto error;
    }

  ssh_cancel_timeouts(SSH_ALL_CALLBACKS, neg);
  /* Insert expire timer allowing the sa to exists for a while (for
     bootstrap) */
  t = ssh_time();
  if (t < pm_info->sa_expire_time)
    t = pm_info->sa_expire_time - t;
  else
    t = 0;

  t = (t < 30) ? 30 : t;
  ssh_xregister_timeout((SshUInt32) t, 0,
                       ike_call_ike_remove_isakmp_sa,
                       neg);
  return neg;
 error:
  if (sa != NULL)
    {
      if (sa->isakmp_negotiation == NULL)
        {
          ike_sa_delete(server->isakmp_context, sa);
          ssh_free(sa);
        }
      else
        ike_delete_negotiation(sa->isakmp_negotiation);
    }
  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  return NULL;
}
コード例 #7
0
ファイル: sshfileio.c プロジェクト: patrick-ken/kernel_808l
/* Read binary file from the disk giving a size limit for the
   file. Return mallocated buffer and the size of the buffer. If the
   reading of file failes return FALSE. If the file name is NULL or
   "-" then read from the stdin. The size_limit is in bytes. If zero
   is used, the read file will try to read the whole file.

   If the file size exceeds the size_limit (given in bytes), FALSE
   is returned.  */
Boolean ssh_read_file_with_limit(const char *file_name,
                                 SshUInt32 size_limit,
                                 unsigned char **buf,
                                 size_t *buf_len)
{
  FILE *fp = NULL;
  unsigned char *iobuf = NULL, *tmp;  
  size_t len, plen, growth, t, offset, ret;

#ifdef WINDOWS
  WCHAR *file = NULL;
  DWORD name_len;
#endif /* WINDOWS */

  /* Read the file */
  if (file_name == NULL || strcmp(file_name, "-") == 0)
    {
      fp = stdin;
      file_name = NULL;
    }
  else

#ifdef WINDOWS
    {
      if ((name_len = MultiByteToWideChar(CP_UTF8, 0, 
                                          file_name, -1, NULL, 0)) == 0)
        {
          SSH_DEBUG(SSH_D_FAIL, ("Multibyte conversion failed"));
          goto failed;
        }
      if (!(file = ssh_malloc((name_len) * sizeof *file)))
        {
          SSH_DEBUG(SSH_D_FAIL, ("allocation failed for file name"));
          goto failed;
        }
      if ((MultiByteToWideChar(CP_UTF8, 0, file_name, -1, 
                                       file, name_len)) == 0)
        {
          SSH_DEBUG(SSH_D_FAIL, ("Multibyte conversion failed"));
          goto failed;
        }      

      fp = _wfopen(file, L"rb");
    }
#else /* WINDOWS */
    fp = fopen(file_name, "rb");
#endif /* WINDOWS */

  if (fp == NULL)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Can't open file for reading"));
      goto failed;
    }

  offset = 0;
  growth = len = plen = FILEBUF_SIZE;
  if ((iobuf = ssh_malloc(len)) == NULL)
    goto failed;

  /* Read the file */
  while ((ret = fread(iobuf + offset, 1, growth, fp)) == growth)
    {
      offset += growth;
      SSH_FILEIO_CHECK_MAX_SIZE;

      /* Fibonacci series on buffer size growth */
      t = len;
      len += plen;
      growth = plen;
      plen = t;

      SSH_DEBUG(SSH_D_HIGHOK,
                ("Growing input buffer from %zd to %zd bytes",
                 plen, len));
      if ((tmp = ssh_realloc(iobuf, plen, len)) == NULL)
        goto failed;
      iobuf = tmp;
    }

  SSH_DEBUG(SSH_D_HIGHOK,
            ("Last read from file %zd bytes to offset %zd, total %zd bytes.",
             ret, offset, ret+offset));

  if (ferror(fp))
    goto failed;

  offset += ret;
  SSH_FILEIO_CHECK_MAX_SIZE;

#ifdef WINDOWS
  if (file)
    {
      fclose(fp);
      ssh_free(file);
    }
#else /* WINDOWS */

  if (file_name)
    fclose(fp);
#endif /* WINDOWS */

  *buf = iobuf;
  *buf_len = offset;
  return TRUE;

 failed:

#ifdef WINDOWS
  if (file)
    ssh_free(file);
#endif /* WINDOWS */

  if (file_name && fp)
    fclose(fp);

  if (iobuf)
    ssh_free(iobuf);

  return FALSE;
}
コード例 #8
0
/* Read /etc/resolv.conf and configure the resolver from it. */
Boolean ssh_dns_resolver_read_resolv_conf(SshDNSResolver resolver,
        unsigned char *name)
{
#ifndef VXWORKS
    unsigned char *buffer, *p, *q, c;
    SshIpAddrStruct address[1];
    size_t buffer_len;
    int i;

    if (!ssh_read_file_with_limit((char *)name, 65536, &buffer, &buffer_len))
        return FALSE;

    ssh_dns_resolver_safety_belt_clear(resolver);

    i = 0;
    p = buffer;
    while (buffer_len > 0)
    {
        SKIP_SPACE(p, buffer_len);
        if (buffer_len < 10)
            break;
        if (strncasecmp((char *)p, "nameserver", 9) == 0 && isspace(p[10]))
        {
            p += 10;
            buffer_len -= 10;
            SKIP_SPACE(p, buffer_len);
            q = p;
            FIND_SPACE(q, buffer_len);
            c = *q;
            *q = '\0';
            if (ssh_ipaddr_parse(address, p))
            {
                ssh_dns_resolver_safety_belt_add(resolver, 1, address);
                i++;
            }
            *q = c;
            p = q;
        }
        FIND_NEWLINE(p, buffer_len);
    }
    ssh_free(buffer);
    if (i == 0)
        return FALSE;
    return TRUE;
#else /* VXWORKS */
    /* Get name server addresses from VxWorks name resolver.
       VxWorks resolver is enabled
       by defining:
   #define INCLUDE_DNS_RESOLVER
   #define RESOLVER_DOMAIN_SERVER  "90.0.0.3"
   #define RESOLVER_DOMAIN         "wrs.com"
       In $WIND_BASE/target/config/xxx/config.h or
       $WIND_BASEtarget/config/all/configAll.h.
       If INCLUDE_DNS_RESOLVER is not defined, VxWorks returns name
       server address 0.0.0.0.
    */
    int i, addr_cnt;
    RESOLV_PARAMS_S resolv_params;
    SshIpAddrStruct address[1];

    ssh_dns_resolver_safety_belt_clear(resolver);

    resolvParamsGet(&resolv_params);
    for(addr_cnt = i = 0; i < MAXNS; i++)
    {
        if (ssh_ipaddr_parse(address, resolv_params.nameServersAddr[i]))
        {
            ssh_dns_resolver_safety_belt_add(resolver, 1, address);
            addr_cnt++;
        }
    }
    return addr_cnt > 0;
#endif
}
コード例 #9
0
/* Parse the result of the AAAA query, and call callback. */
void ssh_name_server_result_aaaa(SshDNSResponseCode error,
                                 SshDNSRRset rrset,
                                 void *context)
{
    SshNameServerOperation operation = context;
    unsigned char internal_buffer[256], *buffer, *p;
    SshIpAddrStruct address[1];
    size_t len;
    int i;

    operation->handle = NULL;

    if (error == SSH_DNS_OK && rrset != NULL)
    {
        if (rrset->state == SSH_DNS_RRSET_NODATA)
        {
            rrset = NULL;
        }
    }
    else
    {
        rrset = NULL;
    }
    if (error == SSH_DNS_TIMEOUT)
        operation->timed_out = TRUE;

    len = 0;
    if (operation->rrset)
    {
        /* Count number of ipv4 addresses. Each address takes 16 bytes
        + comma. */
        len += operation->rrset->number_of_rrs * 17;
    }
    if (rrset)
    {
        /* Count number of ipv6 addresses. Each address takes 40 bytes
        + comma. */
        len += rrset->number_of_rrs * 41;
    }
    if (len >= sizeof(internal_buffer))
    {
        buffer = ssh_malloc(len);
        if (buffer == NULL)
        {
            operation->callback(SSH_TCP_FAILURE, buffer, operation->context);
            goto out;
        }
    }
    else
    {
        buffer = internal_buffer;
    }

    p = buffer;
    if (operation->rrset)
    {
        for(i = 0; i < operation->rrset->number_of_rrs; i++)
        {
            if (operation->rrset->array_of_rdlengths[i] != 4)
                continue;
            SSH_IP_DECODE(address, operation->rrset->array_of_rdata[i],
                          operation->rrset->array_of_rdlengths[i]);
            ssh_ipaddr_print(address, p, buffer + len - p);
            p += strlen((char *)p);
            *p++ = ',';
        }
    }
    if (rrset)
    {
        for(i = 0; i < rrset->number_of_rrs; i++)
        {
            if (rrset->array_of_rdlengths[i] != 16)
                continue;
            SSH_IP_DECODE(address, rrset->array_of_rdata[i],
                          rrset->array_of_rdlengths[i]);
            ssh_ipaddr_print(address, p, buffer + len - p);
            p += strlen((char *)p);
            *p++ = ',';
        }
    }
    if (p != buffer)
    {
        p--;
    }
    *p = '\0';
    if (strlen((char *)buffer) == 0)
        operation->callback(operation->timed_out ? SSH_TCP_TIMEOUT :
                            SSH_TCP_NO_ADDRESS, NULL, operation->context);
    else
        operation->callback(SSH_TCP_OK, buffer, operation->context);
    if (len >= sizeof(internal_buffer))
        ssh_free(buffer);
out:
    ssh_name_server_result_end(operation);
}
コード例 #10
0
static Boolean ssh_dns_resolver_get_xp(SshDNSResolver resolver)
{
    HMODULE  module;
    p_get_adapters_addresses get_adapters_addresses;
    IP_ADAPTER_ADDRESSES *adapter_addresses, *adapter;
    IP_ADAPTER_DNS_SERVER_ADDRESS *dns_address;
    SshUInt32 size;
    SshUInt32 result;
    SshIpAddrStruct address[1];
    Boolean added = FALSE;

    module = LoadLibrary(TEXT("iphlpapi"));
    if (module == NULL)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Unable to load iphelper library"));
        return FALSE;
    }

    get_adapters_addresses
        = (p_get_adapters_addresses)
          GetProcAddress(module, TEXT("GetAdaptersAddresses"));
    if (get_adapters_addresses == NULL)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Could not find GetAdaptersAddresses"
                               " function in the library"));
        goto exit_function;
    }

    result = get_adapters_addresses(AF_UNSPEC,
                                    GAA_FLAG_SKIP_ANYCAST |
                                    GAA_FLAG_SKIP_FRIENDLY_NAME |
                                    GAA_FLAG_SKIP_MULTICAST,
                                    NULL,
                                    NULL,
                                    &size);
    if (result != ERROR_BUFFER_OVERFLOW)
    {
        SSH_DEBUG(SSH_D_FAIL,
                  ("Unable to get the size of Interface info. Error is %d",
                   result));
        goto exit_function;
    }

    adapter_addresses = ssh_calloc(1, size);
    if (adapter_addresses == NULL)
    {
        SSH_DEBUG(SSH_D_FAIL,
                  ("Unable to allocate memory"));
        goto exit_function;
    }
    result = get_adapters_addresses(AF_UNSPEC,
                                    GAA_FLAG_SKIP_ANYCAST |
                                    GAA_FLAG_SKIP_FRIENDLY_NAME |
                                    GAA_FLAG_SKIP_MULTICAST,
                                    NULL,
                                    adapter_addresses,
                                    &size);
    if (result != NO_ERROR)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Call to GetAdaptersAddresses failed."
                               " Error 0x%x", result));
        goto exit_function;
    }

    adapter = adapter_addresses;
    while (adapter)
    {
        if ((adapter->OperStatus != IfOperStatusUp) ||
                (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) ||
                (adapter->IfType == IF_TYPE_TUNNEL))
            goto loop;

        dns_address = (PIP_ADAPTER_DNS_SERVER_ADDRESS)
                      adapter->FirstDnsServerAddress;
        while (dns_address)
        {
            if (((SOCKADDR *)dns_address->Address.lpSockaddr)->sa_family
                    == AF_INET)
                SSH_IP4_DECODE(address,
                               &((PSOCKADDR_IN)dns_address->Address.lpSockaddr)
                               ->sin_addr.s_addr);
            else if (((SOCKADDR *)dns_address->Address.lpSockaddr)->sa_family
                     == AF_INET6)
                SSH_IP6_DECODE(address,
                               &((PSOCKADDR_IN6)dns_address->Address.lpSockaddr)
                               ->sin6_addr.s6_addr);
            else
                goto next;

            ssh_dns_resolver_safety_belt_add(resolver, 1, address);
            added = TRUE;
            SSH_DEBUG(SSH_D_NICETOKNOW, ("Added DNS server %@",
                                         ssh_ipaddr_render,
                                         address));
next:
            dns_address = dns_address->Next;
        }
loop:
        adapter = adapter->Next;
    }
    ssh_free(adapter_addresses);
exit_function:
    FreeLibrary(module);
    return added;


}
コード例 #11
0
static ssh_dns_resolver_get_2k(SshDNSResolver resolver)
{
    HMODULE  module;
    p_get_interface_info get_interface_info;
    p_get_per_adapter_info get_per_adapter_info;
    IP_INTERFACE_INFO *interface_info;
    IP_ADAPTER_INDEX_MAP *adapter_map;
    IP_PER_ADAPTER_INFO  *adapter_info;
    IP_ADDR_STRING  *addr_string;
    SshInt32 count;
    SshUInt32 result;
    SshUInt32 info_len = 0;
    Boolean added = FALSE;
    SshIpAddrStruct address[1];

    module = LoadLibrary(TEXT("iphlpapi"));
    if (module == NULL)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Unable to load iphelper library"));
        return FALSE;
    }

    get_interface_info
        = (p_get_interface_info)GetProcAddress(module,
                TEXT("GetInterfaceInfo"));
    get_per_adapter_info
        = (p_get_per_adapter_info)GetProcAddress(module,
                TEXT("GetPerAdapterInfo"));
    if (get_interface_info == NULL ||
            get_per_adapter_info == NULL)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Could not find necessary"
                               " functions in the library"));
        goto exit_function;
    }

    result = get_interface_info(NULL, &info_len);
    if (ERROR_INSUFFICIENT_BUFFER != result)
    {
        SSH_DEBUG(SSH_D_FAIL,
                  ("Unable to get the size of Interface info. Error is %d",
                   result));
        goto exit_function;
    }

    interface_info = ssh_calloc(1, info_len);
    if (NULL == interface_info)
    {
        SSH_DEBUG(SSH_D_FAIL, ("Unable to allocate memory"));
        goto exit_function;
    }
    result = get_interface_info(interface_info, &info_len);
    if (NO_ERROR != result)
    {
        SSH_DEBUG(SSH_D_FAIL,
                  ("Failed to Get Interface information. Error is %d", result));
        goto exit_function;
    }

    for (count = 0; count < interface_info->NumAdapters; count++)
    {
        adapter_map = (IP_ADAPTER_INDEX_MAP *)&(interface_info->Adapter[count]);
        info_len = 0;

        result = get_per_adapter_info(adapter_map->Index, NULL, &info_len);
        if (ERROR_BUFFER_OVERFLOW == result)
        {
            adapter_info = ssh_calloc(1, info_len);
            if (NULL == adapter_info)
            {
                SSH_DEBUG(SSH_D_FAIL, ("Unable to allocate memory"));
                break;
            }

            result = get_per_adapter_info(adapter_map->Index,
                                          adapter_info,
                                          &info_len);
            if (NO_ERROR == result)
            {
                addr_string = &(adapter_info->DnsServerList);
                while (addr_string !=NULL)
                {
                    if (ssh_ipaddr_parse(address,
                                         addr_string->IpAddress.String))
                    {
                        ssh_dns_resolver_safety_belt_add(resolver, 1, address);

                        added = TRUE;

                        SSH_DEBUG(SSH_D_NICETOKNOW, ("Added DNS server %@",
                                                     ssh_ipaddr_render,
                                                     address));
                    }

                    addr_string = addr_string->Next;
                }
            }
            else
            {
                /* Failed for this adapter. Lets continue for other adapters */
                SSH_DEBUG(SSH_D_FAIL,
                          ("Failed to get adapter info for index %d. "
                           "Error is %d", count, result));
            }

            ssh_free(adapter_info);
        }
        else
        {
            SSH_DEBUG(SSH_D_FAIL,
                      ("Failed to get adapter info len for index %d. "
                       "Error is %d", count, result));
        }
    }
exit_function:
    ssh_free(interface_info);
    FreeLibrary(module);
    return added;
}
コード例 #12
0
/* Looks up all ip-addresses of the host, returning them as a
   comma-separated list when calling the callback.  The host name may
   already be an ip address, in which case it is returned directly. */
SshOperationHandle
ssh_tcp_get_host_addrs_by_name(const unsigned char *name,
                               SshLookupCallback callback,
                               void *context)
{
    SshIpAddrStruct address[1];

    if (ssh_name_server_data == NULL)
        ssh_name_server_init(NULL);

    /* Check if it is IPv6 address in [addr] format. */
    if (*name == '[')
    {
        unsigned char *ret;
        size_t len;

        ret = ssh_strdup(name + 1);
        if (ret == NULL)
        {
            callback(SSH_TCP_FAILURE, NULL, context);
            return NULL;
        }
        len = strlen((char *)ret);
        if (len > 0)
        {
            if (ret[len - 1] == ']')
            {
                ret[len - 1] = '\0';
                if (ssh_ipaddr_parse(address, ret))
                {
                    callback(SSH_TCP_OK, ret, context);
                    ssh_free(ret);
                    return NULL;
                }
            }
        }
        ssh_free(ret);
    }
    /* First check if it is already an ip address. */
    if (ssh_ipaddr_parse(address, name))
    {
        callback(SSH_TCP_OK, name, context);
        return NULL;
    }

    if (strcasecmp((char *)name, "localhost") == 0 ||
            strcasecmp((char *)name, "localhost.") == 0)
    {
#ifdef WITH_IPV6
        callback(SSH_TCP_OK, (unsigned char *)"127.0.0.1,::1", context);
#else /* WITH_IPV6 */
        callback(SSH_TCP_OK, (unsigned char*)"127.0.0.1", context);
#endif /* WITH_IPV6 */
        return NULL;
    }

#ifdef SSHDIST_UTIL_DNS_RESOLVER
#ifndef ENABLE_SYSTEM_DNS_RESOLVER
    if (ssh_name_server_data && !ssh_name_server_data->use_system)
        return ssh_tcp_get_host_addrs_by_name_dns(name, callback, context);
#endif /* ENABLE_SYSTEM_DNS_RESOLVER */
#endif /* SSHDIST_UTIL_DNS_RESOLVER */
    return ssh_tcp_get_host_addrs_by_name_system(name, callback, context);
}
コード例 #13
0
ファイル: hydra-sshkey.c プロジェクト: Dit81/thc-hydra
int start_sshkey(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp) {
  char *empty = "";
  char *login, *key, keep_login[300];
  int auth_state = 0, rc = 0;
  ssh_private_key privkey;

  if (strlen(login = hydra_get_next_login()) == 0)
    login = empty;
  if (strlen(key = hydra_get_next_password()) == 0)
    key = empty;

  if (new_session) {
    if (session) {
      ssh_disconnect(session);
      ssh_finalize();
      ssh_free(session);
    }

    session = ssh_new();
    ssh_options_set(session, SSH_OPTIONS_PORT, &port);
    ssh_options_set(session, SSH_OPTIONS_HOST, hydra_address2string(ip));
    ssh_options_set(session, SSH_OPTIONS_USER, login);
    ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
    ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
    if (ssh_connect(session) != 0) {
      //if the connection was drop, exit and let hydra main handle it
      if (verbose)
        hydra_report(stderr, "[ERROR] could not connect to target port %d\n", port);
      return 3;
    }

    if ((rc = ssh_userauth_none(session, NULL)) == SSH_AUTH_ERROR) {
      return 3;
    } else if (rc == SSH_AUTH_SUCCESS) {
      hydra_report_found_host(port, ip, "sshkey", fp);
      hydra_completed_pair_found();
      if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
        return 2;
      else
        return 1;
    }
  } else
    new_session = 1;

  auth_state = ssh_auth_list(session);
  if ((auth_state & SSH_AUTH_METHOD_PUBLICKEY) > 0) {
    privkey = privatekey_from_file(session, key, 0, NULL);
    if (!privkey) {
      hydra_report(stderr, "[ERROR] skipping invalid private key: \"%s\"\n", key);
      hydra_completed_pair();
      if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
        return 2;

      return 1;
    }
    auth_state = ssh_userauth_pubkey(session, NULL, NULL, privkey);
  } else {
    return 4;
  }

  if (auth_state == SSH_AUTH_ERROR) {
    new_session = 1;
    return 1;
  }

  if (auth_state == SSH_AUTH_SUCCESS || auth_state == SSH_AUTH_PARTIAL) {
    hydra_report_found_host(port, ip, "sshkey", fp);
    hydra_completed_pair_found();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 2;
    return 1;
  } else {
    strncpy(keep_login, login, sizeof(keep_login) - 1);
    keep_login[sizeof(keep_login) - 1] = '\0';
    hydra_completed_pair();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 2;
    login = hydra_get_next_login();
    if (strcmp(login, keep_login) == 0)
      new_session = 0;
    return 1;
  }

  /* not reached */
  return 1;
}
コード例 #14
0
/* Process audit requests from the policymanager. */
void
ssh_engine_pme_get_audit_events(SshEngine engine, SshUInt32 num_events,
				SshPmeAuditCB callback,
				void *callback_context)
{
  SshEngineAuditEvent events, event;
  SshUInt32 i, j, max_events, events_to_send;
  SshUInt32 audit_flags, current_size = 0;
  Boolean more_events = FALSE;

  SSH_ASSERT(callback != NULL_FNPTR);

  ssh_kernel_mutex_lock(engine->flow_control_table_lock);

  audit_flags = engine->audit_flags;
  /* Clear the audit flags. */
  engine->audit_flags = 0;

  max_events = 0;
  for (i = 0; i < SSH_ENGINE_NUM_AUDIT_LEVELS; i++)
    {
      /* Compute the maximum number of events to send */
      if (engine->audit_table_tail[i] >= engine->audit_table_head[i])
	{
	  max_events += 
	    engine->audit_table_tail[i] - engine->audit_table_head[i];
	}
      else
	{
	  max_events += engine->audit_table_size -
	    (engine->audit_table_head[i]  - engine->audit_table_tail[i]);
	}
    }

  if (max_events > num_events)
    max_events = num_events;

  if (max_events == 0)
    {
      ssh_kernel_mutex_unlock(engine->flow_control_table_lock);
      (*callback)(engine->pm, FALSE, audit_flags, 0, NULL, callback_context);
      return;
    }

  if ((events = ssh_calloc(max_events, sizeof(SshEngineAuditEventStruct)))
      == NULL)
    {
      ssh_kernel_mutex_unlock(engine->flow_control_table_lock);
      (*callback)(engine->pm, FALSE, audit_flags, 0, NULL, callback_context);
      return;
    }

  events_to_send = 0;
  
  for (i = 0; i < SSH_ENGINE_NUM_AUDIT_LEVELS; i++)
    {
      while (engine->audit_table_head[i] != engine->audit_table_tail[i])
	{
	  event = &engine->audit_table[i][engine->audit_table_head[i]];
	  
	  /* Move ahead in the list. */
	  engine->audit_table_head[i]
	    = SSH_ENGINE_AUDIT_RING_INC(engine, engine->audit_table_head[i]);
	  
	  memcpy((unsigned char *)&events[events_to_send++], 
		 event, sizeof(events[0]));
	  SSH_ASSERT(events_to_send <= max_events);
	  
	  /* Worst case estimate for the encoded size of the event */
	  current_size += 2 * sizeof(*event) + event->packet_len;
	  
	  if ((events_to_send >= max_events) ||
	      (current_size > SSH_MAX_AUDIT_MESSAGE_SIZE))
	    goto send_events;
	}
    }      
  
 send_events:
  
  /* Have we more events available to send to the PM ? */
  for (j = i; j < SSH_ENGINE_NUM_AUDIT_LEVELS; j++)
    {
      if (engine->audit_table_head[j] != engine->audit_table_tail[j])
	{
	  more_events = TRUE;
	  break;
	}
    }
  
  ssh_kernel_mutex_unlock(engine->flow_control_table_lock);

  /* Send the audit events to the PM. */
  (*callback)(engine->pm, more_events, audit_flags, events_to_send, events,
	      callback_context);
  
  /* Free any packet data that may have been attached to the audit events. */
  for (i = 0; i < events_to_send; i++)
    {
      event = &events[i];
      if (event->packet)
	ssh_free(event->packet);
    }

  if (events)
    ssh_free(events);

  if (events_to_send)  
    SSH_DEBUG(SSH_D_MY, ("Sent %d audit events back to the policymanager",
			 (int) events_to_send));
  return;
}
コード例 #15
0
ファイル: kssh.cpp プロジェクト: leblanc-simon/qlaunchoverssh
/**
 * Close the SSH connection
 */
Kssh::~Kssh()
{
    if (this->m_session != NULL) {
        ssh_free(this->m_session);
    }
}
コード例 #16
0
/* Does the name server lookup using internal dns resolver. */
SshOperationHandle
ssh_tcp_get_host_addrs_by_name_dns(const unsigned char *name,
                                   SshLookupCallback callback,
                                   void *context)
{
    SshNameServerOperation operation;
    unsigned char *dns_name;
    unsigned char *p, *q;
    size_t len;

    operation = ssh_calloc(1, sizeof(*operation));
    if (operation == NULL)
    {
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }

    /* Convert the name to dns format. */
    dns_name = ssh_malloc(strlen((char *)name) + 2);
    if (dns_name == NULL)
    {
        ssh_free(operation);
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }
    ssh_ustrcpy(dns_name + 1, name);
    q = dns_name;
    while ((p = ssh_ustrchr(q + 1, '.')) != NULL)
    {
        len = (p - q) - 1;
        if (len > 63)
        {
            ssh_free(dns_name);
            ssh_free(operation);
            callback(SSH_TCP_FAILURE, NULL, context);
            return NULL;
        }
        *q = (char) len;
        q = p;
    }
    len = strlen((char *)q + 1);
    if (len > 63)
    {
        ssh_free(dns_name);
        ssh_free(operation);
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }
    *q = (char) len;

    operation->callback = callback;
    operation->context = context;
    operation->dns_name = dns_name;
    operation->timed_out = FALSE;
    operation->flags = ssh_name_server_data->resolver_find_flags;

    ssh_operation_register_no_alloc(operation->operation_handle,
                                    ssh_name_server_result_abort,
                                    operation);

    /* Ok, the name is now ready, start query. */
    operation->handle =  ssh_dns_resolver_find(ssh_name_server_data->resolver,
                         dns_name, SSH_DNS_RESOURCE_A,
                         ssh_name_server_data->timeout,
                         operation->flags,
                         ssh_name_server_result_a,
                         operation);
    return operation->operation_handle;
}
コード例 #17
0
/* Import id from the buffer and store newly allocated id to the id pointer,
   freeing the old id if such was stored there. If the id_txt pointer is given
   then it is used to store the textual format of the id. If that pointer
   contained old id string it is freed before the new string stored there.
   Returns TRUE if successful and FALSE otherwise. In case of error the buffer
   is left unspecified state (i.e part of it might be consumed). */
Boolean ssh_ike_sa_import_id(SshBuffer buffer, SshIkePayloadID *id,
                             char **id_txt)
{
  SshUInt32 a32, b32, c32;
  SshIkePayloadID newp = NULL;
  char newp_txt[255];
  size_t ret = 0;

  SSH_DEBUG(5, ("Start"));

  if (ssh_decode_buffer
      (buffer,
       SSH_DECODE_UINT32(&a32),
       SSH_FORMAT_END) == 0)
    goto error;

  if (a32 == 0)
    {
      if (id)
        {
          ssh_ike_id_free(*id);
          *id = NULL;
        }
      if (id_txt)
        {
          ssh_free(*id_txt);
          *id_txt = ssh_strdup("No Id");
          if (*id == NULL)
            return FALSE;
        }
      return TRUE;
    }

  newp = ssh_malloc(sizeof(*newp));
  if (newp == NULL)
    return FALSE;

  newp->raw_id_packet = NULL;

  newp->id_type = a32;

  if (ssh_decode_buffer
      (buffer,
       SSH_DECODE_UINT32(&a32),
       SSH_DECODE_UINT32(&b32),
       SSH_DECODE_UINT32(&c32),
       SSH_FORMAT_END) == 0)
    goto error;

  newp->protocol_id = a32;
  newp->port_number = b32;
  newp->port_range_end = c32;

  switch (newp->id_type)
    {
    case IPSEC_ID_IPV4_ADDR:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv4_addr, 4),
         SSH_FORMAT_END);
      newp->identification_len = 4;
      break;
    case IPSEC_ID_FQDN:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_UINT32_STR(&newp->identification.fqdn,
         &newp->identification_len),
         SSH_FORMAT_END);
      break;
    case IPSEC_ID_USER_FQDN:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_UINT32_STR(&newp->identification.user_fqdn,
         &newp->identification_len),
         SSH_FORMAT_END);
      break;
    case IPSEC_ID_IPV4_ADDR_SUBNET:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv4_addr_subnet, 4),
         SSH_DECODE_DATA(newp->identification.ipv4_addr_netmask, 4),
         SSH_FORMAT_END);
      newp->identification_len = 8;
      break;
    case IPSEC_ID_IPV6_ADDR:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv6_addr, 16),
         SSH_FORMAT_END);
      newp->identification_len = 16;
      break;
    case IPSEC_ID_IPV6_ADDR_SUBNET:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv6_addr_subnet, 16),
         SSH_DECODE_DATA(newp->identification.ipv6_addr_netmask, 16),
         SSH_FORMAT_END);
      newp->identification_len = 32;
      break;
    case IPSEC_ID_IPV4_ADDR_RANGE:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv4_addr_range1, 4),
         SSH_DECODE_DATA(newp->identification.ipv4_addr_range2, 4),
         SSH_FORMAT_END);
      newp->identification_len = 8;
      break;
    case IPSEC_ID_IPV6_ADDR_RANGE:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_DATA(newp->identification.ipv6_addr_range1, 16),
         SSH_DECODE_DATA(newp->identification.ipv6_addr_range2, 16),
         SSH_FORMAT_END);
      newp->identification_len = 32;
      break;
    case IPSEC_ID_DER_ASN1_DN:
    case IPSEC_ID_DER_ASN1_GN:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_UINT32_STR(&newp->identification.asn1_data,
         &newp->identification_len),
         SSH_FORMAT_END);
      break;
    case IPSEC_ID_KEY_ID:
      ret = ssh_decode_buffer
        (buffer,
         SSH_DECODE_UINT32_STR(&newp->identification.key_id,
         &newp->identification_len),
         SSH_FORMAT_END);
      break;
#ifdef SSHDIST_IKE_ID_LIST
    case IPSEC_ID_LIST:
      {
        int cnt;
        SshIkePayloadID itemp = NULL;

        newp->identification_len = 0;
        ret = ssh_decode_buffer
          (buffer,
           SSH_DECODE_UINT32((SshUInt32 *)&newp->identification.
			     id_list_number_of_items),
           SSH_FORMAT_END);
        if (ret == 0)
          goto error;
        newp->identification.id_list_items =
          ssh_calloc(newp->identification.id_list_number_of_items,
                     sizeof(newp->identification.id_list_items[0]));
        if (newp->identification.id_list_items == NULL)
          goto error;

        for (cnt = 0;
             cnt < newp->identification.id_list_number_of_items;
             cnt++)
          {
            if (!ssh_ike_sa_import_id(buffer, &itemp, NULL))
              goto error;

            newp->identification.id_list_items[cnt] = *itemp;
            ssh_free(itemp);
            itemp = NULL;
          }
        break;
      }
#endif /* SSHDIST_IKE_ID_LIST */
    }
  if (ret == 0)
    goto error;
  if (id_txt)
    {
      ssh_free(*id_txt);
      ssh_ike_id_to_string(newp_txt, sizeof(newp_txt), newp);
      *id_txt = ssh_strdup(newp_txt);
      if (*id_txt == NULL)
        goto error;
    }
  if (id)
    {
      ssh_ike_id_free(*id);
      *id = newp;
    }
  else
    {
      ssh_ike_id_free(newp);
    }
  return TRUE;
 error:
  if (newp != NULL)
    ssh_ike_id_free(newp);
  return FALSE;
}
コード例 #18
0
/* Parse the reply of the either A or AAAA query, depending of the original PTR
   query name. Call the result callback. */
void ssh_name_server_result_forward(SshDNSResponseCode error,
                                    SshDNSRRset rrset,
                                    void *context)
{
    SshNameServerOperation operation = context;
    unsigned char internal_buffer[256], *buffer;
    size_t len;
    int i;

    operation->handle = NULL;

    if (error == SSH_DNS_OK && rrset != NULL)
    {
        if (rrset->state == SSH_DNS_RRSET_NODATA)
        {
            rrset = NULL;
        }
    }
    else
    {
        rrset = NULL;
    }

    /* If we didn't find the name, then return error. */
    if (rrset == NULL)
    {
        if (error == SSH_DNS_TIMEOUT)
            operation->timed_out = TRUE;
        operation->callback(operation->timed_out ? SSH_TCP_TIMEOUT :
                            SSH_TCP_NO_NAME, NULL, operation->context);
        ssh_name_server_result_end(operation);
        return;
    }

    /* Verify that the original ip-address we are searching for is also in the
       forward map. */
    for(i = 0; i < rrset->number_of_rrs; i++)
    {
        if (rrset->array_of_rdlengths[i] == operation->length &&
                memcmp(rrset->array_of_rdata[i], operation->dns_name,
                       operation->length) == 0)
            break;
    }
    if (i == rrset->number_of_rrs)
    {
        /* Didn't find the original ip from the forward map. */
        operation->callback(SSH_TCP_NO_NAME, NULL, operation->context);
        ssh_name_server_result_end(operation);
        return;
    }

    len = strlen((char *)operation->rrset->array_of_rdata[0]) + 1;
    if (len >= sizeof(internal_buffer))
    {
        buffer = ssh_malloc(len);
        if (buffer == NULL)
        {
            operation->callback(SSH_TCP_FAILURE, NULL, operation->context);
            ssh_name_server_result_end(operation);
            return;
        }
    }
    else
    {
        buffer = internal_buffer;
    }

    ssh_snprintf(buffer, len, "%@", ssh_dns_name_render,
                 operation->rrset->array_of_rdata[0]);
    /* Remove the final dot. */
    i = strlen((char *)buffer);
    if (i > 0 && buffer[i - 1] == '.')
        buffer[i - 1] = '\0';

    /* Call the result callback now. */
    operation->callback(SSH_TCP_OK, buffer, operation->context);
    if (len >= sizeof(internal_buffer))
        ssh_free(buffer);
    ssh_name_server_result_end(operation);
    return;
}
コード例 #19
0
ファイル: pkd_daemon.c プロジェクト: machty/tmate
static int pkd_exec_hello(int fd, struct pkd_daemon_args *args) {
    int rc = -1;
    ssh_bind b = NULL;
    ssh_session s = NULL;
    ssh_event e = NULL;
    ssh_channel c = NULL;
    enum ssh_bind_options_e opts = -1;

    int level = args->opts.libssh_log_level;
    enum pkd_hostkey_type_e type = args->type;
    const char *hostkeypath = args->hostkeypath;

    pkd_state.eof_received = 0;
    pkd_state.close_received  = 0;
    pkd_state.req_exec_received = 0;

    b = ssh_bind_new();
    if (b == NULL) {
        pkderr("ssh_bind_new\n");
        goto outclose;
    }

    if (type == PKD_RSA) {
        opts = SSH_BIND_OPTIONS_RSAKEY;
    } else if (type == PKD_DSA) {
        opts = SSH_BIND_OPTIONS_DSAKEY;
    } else if (type == PKD_ECDSA) {
        opts = SSH_BIND_OPTIONS_ECDSAKEY;
    } else {
        pkderr("unknown kex algorithm: %d\n", type);
        rc = -1;
        goto outclose;
    }

    rc = ssh_bind_options_set(b, opts, hostkeypath);
    if (rc != 0) {
        pkderr("ssh_bind_options_set: %s\n", ssh_get_error(b));
        goto outclose;
    }

    rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY, &level);
    if (rc != 0) {
        pkderr("ssh_bind_options_set log verbosity: %s\n", ssh_get_error(b));
        goto outclose;
    }

    s = ssh_new();
    if (s == NULL) {
        pkderr("ssh_new\n");
        goto outclose;
    }

    /*
     * ssh_bind_accept loads host key as side-effect.  If this
     * succeeds, the given 'fd' will be closed upon 'ssh_free(s)'.
     */
    rc = ssh_bind_accept_fd(b, s, fd);
    if (rc != SSH_OK) {
        pkderr("ssh_bind_accept_fd: %s\n", ssh_get_error(b));
        goto outclose;
    }

    /* accept only publickey-based auth */
    ssh_set_auth_methods(s, SSH_AUTH_METHOD_PUBLICKEY);

    /* initialize callbacks */
    ssh_callbacks_init(&pkd_server_cb);
    pkd_server_cb.userdata = &c;
    rc = ssh_set_server_callbacks(s, &pkd_server_cb);
    if (rc != SSH_OK) {
        pkderr("ssh_set_server_callbacks: %s\n", ssh_get_error(s));
        goto out;
    }

    /* first do key exchange */
    rc = ssh_handle_key_exchange(s);
    if (rc != SSH_OK) {
        pkderr("ssh_handle_key_exchange: %s\n", ssh_get_error(s));
        goto out;
    }

    /* setup and pump event to carry out exec channel */
    e = ssh_event_new();
    if (e == NULL) {
        pkderr("ssh_event_new\n");
        goto out;
    }

    rc = ssh_event_add_session(e, s);
    if (rc != SSH_OK) {
        pkderr("ssh_event_add_session\n");
        goto out;
    }

    /* poll until exec channel established */
    while ((ctx.keep_going != 0) &&
            (rc != SSH_ERROR) && (pkd_state.req_exec_received == 0)) {
        rc = ssh_event_dopoll(e, -1 /* infinite timeout */);
    }

    if (rc == SSH_ERROR) {
        pkderr("ssh_event_dopoll\n");
        goto out;
    } else if (c == NULL) {
        pkderr("poll loop exited but exec channel not ready\n");
        rc = -1;
        goto out;
    }

    rc = ssh_channel_write(c, "hello\n", 6); /* XXX: customizable payloads */
    if (rc != 6) {
        pkderr("ssh_channel_write partial (%d)\n", rc);
    }

    rc = ssh_channel_request_send_exit_status(c, 0);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_request_send_exit_status: %s\n",
               ssh_get_error(s));
        goto out;
    }

    rc = ssh_channel_send_eof(c);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_send_eof: %s\n", ssh_get_error(s));
        goto out;
    }

    rc = ssh_channel_close(c);
    if (rc != SSH_OK) {
        pkderr("ssh_channel_close: %s\n", ssh_get_error(s));
        goto out;
    }

    while ((ctx.keep_going != 0) &&
            (pkd_state.eof_received == 0) &&
            (pkd_state.close_received == 0) &&
            (ssh_channel_is_closed(c) == 0)) {
        rc = ssh_event_dopoll(e, 1000 /* milliseconds */);
        if (rc == SSH_ERROR) {
            pkderr("ssh_event_dopoll for eof + close: %s\n", ssh_get_error(s));
            break;
        } else {
            rc = 0;
        }
    }
    goto out;

outclose:
    close(fd);
out:
    if (c != NULL) {
        ssh_channel_free(c);
    }
    if (e != NULL) {
        ssh_event_remove_session(e, s);
        ssh_event_free(e);
    }
    if (s != NULL) {
        ssh_disconnect(s);
        ssh_free(s);
    }
    if (b != NULL) {
        ssh_bind_free(b);
    }
    return rc;
}
コード例 #20
0
/* Does the name server lookup using internal dns resolver. */
SshOperationHandle
ssh_tcp_get_host_by_addr_dns(const unsigned char *name,
                             SshLookupCallback callback,
                             void *context)
{
    SshNameServerOperation operation;
    unsigned char *dns_name, *p;
    unsigned char buffer[16];
    size_t len;
    int i;

    len = 16;
    if (!ssh_inet_strtobin(name, buffer, &len))
    {
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }

    operation = ssh_calloc(1, sizeof(*operation));
    if (operation == NULL)
    {
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }

    operation->dns_name = ssh_memdup(buffer, len);
    if (operation->dns_name == NULL)
    {
        ssh_free(operation);
        callback(SSH_TCP_FAILURE, NULL, context);
        return NULL;
    }

    if (len == 4)
    {
        /* IPv4 address, convert a.b.c.d to d.c.b.a.in-addr.arpa. Buffer size
        needed is 15 + 13 + 1 = 29. */
        dns_name = ssh_malloc(32);
        if (dns_name == NULL)
        {
            ssh_free(operation);
            callback(SSH_TCP_FAILURE, NULL, context);
            return NULL;
        }
        p = dns_name;
        for(i = 3; i >= 0; i--)
        {
            if (buffer[i] >= 100)
                *p = 3;
            else if (buffer[i] >= 10)
                *p = 2;
            else
                *p = 1;
            ssh_snprintf(p + 1, dns_name + 32 - p - 1,
                         "%d", buffer[i]);
            p += (*p) + 1;
        }
        strcpy((char *)p, "\7in-addr\4arpa");
    }
    else
    {
        /* IPv6 address, convert it to
        p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.
         ip6.arpa.
         Buffer size needed is 32 * 2 + 9 = 73. */
        dns_name = ssh_malloc(80);
        if (dns_name == NULL)
        {
            ssh_free(operation);
            callback(SSH_TCP_FAILURE, NULL, context);
            return NULL;
        }
        p = dns_name;
        for(i = 15; i >= 0; i--)
        {
            *p++ = 1;
            *p++ = "0123456789abcdef"[buffer[i] & 0xf];
            *p++ = 1;
            *p++ = "0123456789abcdef"[buffer[i] >> 4];
        }
        strcpy((char *)p, "\3ip6\4arpa");
    }

    operation->callback = callback;
    operation->context = context;
    operation->length = len;
    operation->timed_out = FALSE;
    operation->flags = ssh_name_server_data->resolver_find_flags;

    ssh_operation_register_no_alloc(operation->operation_handle,
                                    ssh_name_server_result_abort,
                                    operation);

    /* Ok, the name is now ready, start query. */
    operation->handle =  ssh_dns_resolver_find(ssh_name_server_data->resolver,
                         dns_name, SSH_DNS_RESOURCE_PTR,
                         ssh_name_server_data->timeout,
                         operation->flags,
                         ssh_name_server_result_ptr,
                         operation);
    ssh_free(dns_name);
    return operation->operation_handle;
}
コード例 #21
0
ファイル: sftplist.cpp プロジェクト: DTidd/OpenRDAAPI
int main(int argc,char **argv)
#endif
{
	char *env_username=NULL;
	char *env_password=NULL;
	char *env_remote_dir=NULL;
	char *env_remote_file=NULL;
	char *env_remote_server=NULL;
	char *env_temp=NULL;
	int env_remote_port=22;
	int ret=0;
  	ssh_session session;
	char bvalue=FALSE;

	if(argc<5)
	{
		env_username=RDA_GetEnv("SFTP_USERNAME");	
		env_password=RDA_GetEnv("SFTP_PASSWORD");
		env_remote_dir=RDA_GetEnv("SFTP_REMOTE_DIR");
		env_remote_file=RDA_GetEnv("SFTP_REMOTE_FILE");
		env_remote_server=RDA_GetEnv("SFTP_REMOTE_SERVER");
		env_temp=RDA_GetEnv("SFTP_PORT");
		if( (env_username==NULL) && (env_password==NULL) && (env_remote_dir==NULL) && (env_remote_file==NULL) && (env_remote_server==NULL) && (env_temp==NULL) )
		{
			fprintf(stderr,"Not enough arguments specified to continue.\n");
			return(-1);
		}else if( (env_username!=NULL) && (env_password!=NULL) && (env_remote_server!=NULL) )
		{
			pass_word=stralloc(env_password);
			initrdadiag();
			session=connect_ssh(env_remote_server,env_username,FALSE);
			if(session==NULL) return EXIT_FAILURE;
			ret=sftp_list_file(session,env_remote_dir,env_remote_file);
			ssh_disconnect(session);
			ssh_free(session);
			exit(ret);

		}
	}else{
		if(InitializeSubsystems(argc,argv,"ARCHIVE","SFTPLIST")) 
		{
			return(-1);
		}
		bvalue=UsersWorkstationValidated();
		if(!bvalue)
		{
			ShutdownSubsystems();
			return(-1);
		}

		workstation_ip=stralloc(argv[1]);
		docfolder=stralloc(argv[2]);
		logname=stralloc(argv[3]);
		pass_word=stralloc(argv[4]);
		if(argc>5) details=TRUE;
		session=connect_ssh(workstation_ip,logname,FALSE);
		if(session==NULL) return EXIT_FAILURE;
		do_sftp(session);
		ssh_disconnect(session);
		ssh_free(session);
	}
	if(docfolder!=NULL) Rfree(docfolder);
	if(workstation_ip!=NULL) Rfree(workstation_ip);
	if(pass_word!=NULL) Rfree(pass_word);
	if(logname!=NULL) Rfree(logname);
	ShutdownSubsystems();
}
コード例 #22
0
void
ssh_virtual_adapter_configure(SshInterceptor interceptor,
			      SshInterceptorIfnum adapter_ifnum,
			      SshVirtualAdapterState adapter_state,
			      SshUInt32 num_addresses,
			      SshIpAddr addresses,
			      SshVirtualAdapterParams params,
			      SshVirtualAdapterStatusCB callback,
			      void *context)
{
  SshInterceptorVirtualAdapter va;
  SshInterceptorVirtualAdapterOp op;
  SshBufferStruct ip_buffer;
  unsigned char *param_ptr;
  size_t param_len;
  SshUInt32 i;
  SshVirtualAdapterError error = SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR;
  SshIpAddrStruct undefined_ip;

  ssh_buffer_init(&ip_buffer);

  /* Assert that this virtual adapter exists. */
  ssh_mutex_lock(interceptor->mutex);
  for (va = interceptor->virtual_adapters; va; va = va->next)
    if (va->adapter_ifnum == adapter_ifnum)
      break;
  ssh_mutex_unlock(interceptor->mutex);
  SSH_ASSERT(va != NULL);

  /* Encode "clear all addresses" as one undefined address. */
  if (num_addresses == 0 && addresses != NULL)
    {
      SSH_IP_UNDEFINE(&undefined_ip);
      addresses = &undefined_ip;      
      num_addresses = 1;
    }
  
  /* Encode IP addresses. */
  for (i = 0; i < num_addresses; i++)
    {
      if (!ssh_encode_ipaddr_buffer(&ip_buffer, &addresses[i]))
	{
	  error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE;
	  goto error;
	}
    }

  /* Encode params. */
  param_ptr = NULL;
  param_len = 0;
  if (params)
    {      
      if (!ssh_virtual_adapter_param_encode(params, &param_ptr, &param_len))
	{
	  error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE;
	  goto error;
	}
    }

  /* Initialize an operation handle. */
  op = alloc_virtual_adapter_op(interceptor);
  op->status_cb = callback;
  op->context = context;

  SSH_DEBUG(SSH_D_NICETOKNOW, 
	    ("sending configure request for virtual adapter %d to forwarder.",
	     (int) adapter_ifnum));

  /* Send a message to the kernel forwarder module. */
  ssh_usermode_interceptor_send_encode(
                  interceptor,
                  SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_CONFIGURE,
                  SSH_FORMAT_UINT32, op->id,
		  SSH_FORMAT_UINT32, adapter_ifnum,
		  SSH_FORMAT_UINT32, adapter_state,
		  SSH_FORMAT_UINT32, num_addresses,
                  SSH_FORMAT_UINT32_STR, 
		  ssh_buffer_ptr(&ip_buffer), ssh_buffer_len(&ip_buffer),
                  SSH_FORMAT_UINT32_STR, param_ptr, param_len,
                  SSH_FORMAT_END);

  op->handle = ssh_operation_register(virtual_adapter_operation_abort, op);
  ssh_buffer_uninit(&ip_buffer);
  ssh_free(param_ptr);
  return;

 error:
  ssh_buffer_uninit(&ip_buffer);
  ssh_free(param_ptr);

  (*callback)(error, adapter_ifnum, NULL, SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
	      NULL, context);
}
コード例 #23
0
ファイル: mock-sshd.c プロジェクト: cockpit-project/cockpit
static gint
mock_ssh_server (const gchar *server_addr,
                 gint server_port,
                 const gchar *user,
                 const gchar *password,
                 gboolean multi_step)
{
  char portname[16];
  char addrname[16];
  struct sockaddr_storage addr;
  socklen_t addrlen;
  ssh_bind sshbind;
  const char *msg;
  int r;
  gint rounds = 0;

  state.event = ssh_event_new ();
  if (state.event == NULL)
    g_return_val_if_reached (-1);

  sshbind = ssh_bind_new ();
  state.session = ssh_new ();

  if (server_addr == NULL)
    server_addr = "127.0.0.1";

  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDADDR, server_addr);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDPORT, &server_port);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_RSAKEY, SRCDIR "/src/ssh/mock_rsa_key");
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_DSAKEY, SRCDIR "/src/ssh/mock_dsa_key");

  /* Known issue with recent libssh versions on 32bits: avoid using
   * curve25519-sha256.  See https://bugs.libssh.org/T151
   */
  if (sizeof (void *) == 4)
    ssh_options_set (state.session, SSH_OPTIONS_KEY_EXCHANGE, "ecdh-sha2-nistp256, diffie-hellman-group18-sha512, diffie-hellman-group16-sha512, diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1, diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1");

  if (ssh_bind_listen (sshbind) < 0)
    {
      g_critical ("couldn't listen on socket: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.bind_fd = ssh_bind_get_fd (sshbind);
  state.user = user;
  state.password = password;
  state.multi_step = multi_step;
  ssh_pki_import_pubkey_file (SRCDIR "/src/ssh/test_rsa.pub",
                              &state.pkey);
  state.buffer = g_byte_array_new ();

  /* Print out the port */
  if (server_port == 0)
    {
      addrlen = sizeof (addr);
      if (getsockname (state.bind_fd, (struct sockaddr *)&addr, &addrlen) < 0)
        {
          g_critical ("couldn't get local address: %s", g_strerror (errno));
          return 1;
        }
      r = getnameinfo ((struct sockaddr *)&addr, addrlen, addrname, sizeof (addrname),
                       portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV);
      if (r != 0)
        {
          g_critical ("couldn't get local port: %s", gai_strerror (r));
          return 1;
        }

      /* Caller wants to know the port */
      g_print ("%s\n", portname);
    }

  /* Close stdout (once above info is printed) */
  close (1);

  ssh_set_message_callback (state.session, authenticate_callback, &rounds);

  r = ssh_bind_accept (sshbind, state.session);
  if (r == SSH_ERROR)
    {
      g_critical ("accepting connection failed: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.session_fd = ssh_get_fd (state.session);

  if (ssh_handle_key_exchange (state.session))
    {
      msg = ssh_get_error (state.session);
      if (!strstr (msg, "_DISCONNECT"))
        g_critical ("key exchange failed: %s", msg);
      return 1;
    }

  if (ssh_event_add_session (state.event, state.session) != SSH_OK)
    g_return_val_if_reached (-1);

  do
    {
      ssh_event_dopoll (state.event, 10000);
    }
  while (ssh_is_connected (state.session));

  ssh_event_remove_session (state.event, state.session);
  ssh_event_free (state.event);
  ssh_free (state.session);
  ssh_key_free (state.pkey);
  g_byte_array_free (state.buffer, TRUE);
  ssh_bind_free (sshbind);

  return 0;
}
コード例 #24
0
void
ikev2_fb_sa_handler(SshIkeNegotiation negotiation,
		    SshIkePMPhaseQm pm_info,
		    int number_of_sas, SshIkeIpsecSelectedSA sas,
		    SshIkeIpsecKeymat keymat,
		    void *sa_callback_context)
{
  SshIkev2FbNegotiation neg;

  neg = SSH_IKEV2_FB_QM_GET_P1_NEGOTIATION(pm_info);
  if (neg == NULL)
    return;

  neg->ike_sa->last_input_stamp = ssh_time();

  SSH_DEBUG(SSH_D_LOWOK, ("SA handler entered, IKE SA %p (neg %p)",
			  pm_info->phase_i->policy_manager_data, neg));

  if (number_of_sas != 1)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Quick-Mode does not result in one bundle"));
      goto error;
    }

  if (neg->ed->callback)
    {
      int i, iproto;
      SshIkev2PayloadTransform *t;
      SshIkeIpsecSelectedProtocol p;
      SshIkeIpsecAttributeEncapsulationModeValues encap;

      /* Assert that `neg->qm_info' is set correctly. */
      SSH_ASSERT(neg->qm_info == pm_info);

      for (i = 0; i < SSH_IKEV2_TRANSFORM_TYPE_MAX; i++)
	neg->ed->ipsec_ed->ipsec_sa_transforms[i] = &neg->transforms[i];

      /* Fill in the selected transforms into ipsec_ed */

      t = neg->ed->ipsec_ed->ipsec_sa_transforms;

      for (iproto = 0; iproto < sas[0].number_of_protocols; iproto++)
	{
	  p = &sas[0].protocols[iproto];
	  if (p->protocol_id == SSH_IKE_PROTOCOL_IPSEC_ESP)
	    {
	      t[SSH_IKEV2_TRANSFORM_TYPE_ENCR]->id =
		ikev2_fb_v1_esp_id_to_v2_id(p->transform_id.generic);
	      if (p->attributes.key_length)
		t[SSH_IKEV2_TRANSFORM_TYPE_ENCR]->transform_attribute =
		  (0x800e << 16) | p->attributes.key_length;

	      if (p->attributes.auth_algorithm)
		t[SSH_IKEV2_TRANSFORM_TYPE_INTEG]->id =
		  ikev2_fb_v1_auth_id_to_v2_id(p->attributes.auth_algorithm);
	      else
		t[SSH_IKEV2_TRANSFORM_TYPE_INTEG] = NULL;
	    }
	  else if (p->protocol_id == SSH_IKE_PROTOCOL_IPSEC_AH)
	    {
	      t[SSH_IKEV2_TRANSFORM_TYPE_INTEG]->id =
		ikev2_fb_v1_ah_id_to_v2_id(p->transform_id.generic);
	      t[SSH_IKEV2_TRANSFORM_TYPE_ENCR] = NULL;
	    }
	  else if (p->protocol_id == SSH_IKE_PROTOCOL_IPCOMP)
	    {
	      if (p->spi_size_out == 2)
		{
		  int j;

		  for (j = 0; j < neg->ipcomp_num; j++)
		    {
		      if (neg->ipcomp_algs[j] == p->transform_id.ipcomp)
			{
			  neg->ipcomp_num = 1;
			  neg->ipcomp_algs[0] = p->transform_id.ipcomp;
			  neg->ipcomp_cpi_out[0] = SSH_GET_16BIT(p->spi_out);
			  break;
			}
		    }
		}
	    }

	  if (p->attributes.group_desc)
	    t[SSH_IKEV2_TRANSFORM_TYPE_D_H]->id = p->attributes.group_desc;
	  else
	    t[SSH_IKEV2_TRANSFORM_TYPE_D_H] = NULL;

	  t[SSH_IKEV2_TRANSFORM_TYPE_ESN]->id = (p->attributes.longseq_size)
	    ? SSH_IKEV2_TRANSFORM_ESN_ESN
	    : SSH_IKEV2_TRANSFORM_ESN_NO_ESN;

	  /* For initiator, notify policymanager about transport mode */
	  encap = p->attributes.encapsulation_mode;
	  if (encap == IPSEC_VALUES_ENCAPSULATION_MODE_TRANSPORT ||
	      encap == IPSEC_VALUES_ENCAPSULATION_MODE_UDP_TRANSPORT ||
	      encap == IPSEC_VALUES_ENCAPSULATION_MODE_UDP_DRAFT_TRANSPORT)
	    {
	      (void)
		ikev2_fb_construct_notify(neg,
					  0,
					  SSH_IKEV2_NOTIFY_USE_TRANSPORT_MODE,
					  TRUE,
					  0, NULL, 0, NULL);
	    }
	}

      if (neg->ipcomp_num > 0)
	{
	  for (i = 0; i < neg->ipcomp_num; i++)
	    {
	      unsigned char data[3];

	      SSH_PUT_16BIT(data, neg->ipcomp_cpi_out[i]);
	      data[2] = neg->ipcomp_algs[i];

	      (void)
		ikev2_fb_construct_notify(neg,
					  0,
					  SSH_IKEV2_NOTIFY_IPCOMP_SUPPORTED,
					  TRUE,
					  0, NULL, sizeof(data), data);
	    }
	}
    }

  /* Set the outbound SPI to the IPSec exchange data */
  if (sas->protocols[0].spi_size_out != 4)
    goto error;
  neg->ed->ipsec_ed->spi_outbound = SSH_GET_32BIT(sas->protocols[0].spi_out);

  SSH_DEBUG(SSH_D_LOWOK, ("Outbound SPI %lx",
			  (unsigned long) neg->ed->ipsec_ed->spi_outbound));

  if (!ikev2_fb_fill_keymat(neg->ed, negotiation, sas, keymat))
    {
      SSH_DEBUG(SSH_D_FAIL, ("Cannot generate IKEv2 keying material"));
      goto error;
    }

  SSH_IKEV2_FB_V2_CALL(neg, ipsec_sa_install)
    (neg->server->sad_handle, neg->ed, ikev2_fb_ipsec_sa_install_done, neg);
  return;

 error:

  /* Even in the case of error, we call the IKEv2 SA installation
     policy call. The key material is cleared to ensure the installation
     will fail at the policy manager. */
  ssh_free(neg->ed->ipsec_ed->ikev1_keymat);
  neg->ed->ipsec_ed->ikev1_keymat = NULL;
  neg->ed->ipsec_ed->ikev1_keymat_len = 0;

  SSH_IKEV2_FB_V2_CALL(neg, ipsec_sa_install)
    (neg->server->sad_handle, neg->ed, ikev2_fb_ipsec_sa_install_done, neg);
}
コード例 #25
0
ファイル: torture_misc.c プロジェクト: dirk/node-libssh
static void teardown(void **state) {
    ssh_free(*state);
}
コード例 #26
0
Boolean
ssh_radius_url_set_avpset_avp(SshRadiusUrlAvpSet avp_set,
                              SshRadiusAvpType avp_type,
                              SshUInt8 *buf,
                              SshUInt8 len)
{
  size_t i;
  SshUInt8 *new_buf;
  SshRadiusUrlAvp avp;

  SSH_PRECOND(avp_set != NULL);

  /* First see if we can get a buffer for the contents of the AVP */

  avp = NULL;
  new_buf = NULL;

  if (buf != NULL)
    {
      new_buf = ssh_malloc(len);
      if (new_buf == NULL)
        return FALSE;

      memcpy(new_buf, buf, len);
    }

  /* .. then try to enlarge the AVP set in such a manner that it does
     not break if we run out of memory.. */

  for (i = 0; i < avp_set->navps; i++)
    {
      if (avp_set->avp[i].type == avp_type)
        break;
    }

  if (i == avp_set->navps)
    {
      avp = ssh_malloc((avp_set->navps+1)*sizeof(SshRadiusUrlAvpStruct));

      if (avp == NULL)
        return FALSE;

      avp_set->navps++;

      memcpy(avp, avp_set->avp,
             (avp_set->navps)*sizeof(SshRadiusUrlAvpStruct));

      ssh_free(avp_set->avp);
      avp_set->avp = avp;

      avp[i].type = 0;
      avp[i].buf = NULL;
      avp[i].len = 0;
    }
  else
    {
      avp = avp_set->avp;
      
      if (avp[i].buf != NULL)
        ssh_free(avp[i].buf);
      avp[i].buf = NULL;
      avp[i].len = 0;
      avp[i].type = 0;
    }


  avp[i].buf = new_buf;
  avp[i].len = len;
  avp[i].type = avp_type;
  return TRUE;
}
コード例 #27
0
ファイル: libssh_scp.c プロジェクト: ShiftMediaProject/libssh
static int open_location(struct location *loc, int flag) {
    if (loc->is_ssh && flag == WRITE) {
        loc->session = connect_ssh(loc->host, loc->user, verbosity);
        if (!loc->session) {
            fprintf(stderr, "Couldn't connect to %s\n", loc->host);
            return -1;
        }

        loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
        if (!loc->scp) {
            fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
            ssh_disconnect(loc->session);
            ssh_free(loc->session);
            loc->session = NULL;
            return -1;
        }

        if (ssh_scp_init(loc->scp) == SSH_ERROR) {
            fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
            ssh_scp_free(loc->scp);
            loc->scp = NULL;
            ssh_disconnect(loc->session);
            ssh_free(loc->session);
            loc->session = NULL;
            return -1;
        }
        return 0;
    } else if (loc->is_ssh && flag == READ) {
        loc->session = connect_ssh(loc->host, loc->user, verbosity);
        if (!loc->session) {
            fprintf(stderr, "Couldn't connect to %s\n", loc->host);
            return -1;
        }

        loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path);
        if (!loc->scp) {
            fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
            ssh_disconnect(loc->session);
            ssh_free(loc->session);
            loc->session = NULL;
            return -1;
        }

        if (ssh_scp_init(loc->scp) == SSH_ERROR) {
            fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
            ssh_scp_free(loc->scp);
            loc->scp = NULL;
            ssh_disconnect(loc->session);
            ssh_free(loc->session);
            loc->session = NULL;
            return -1;
        }
        return 0;
    } else {
        loc->file = fopen(loc->path, flag == READ ? "r":"w");
        if (!loc->file) {
            if (errno == EISDIR) {
                if (chdir(loc->path)) {
                    fprintf(stderr,
                            "Error changing directory to %s: %s\n",
                            loc->path, strerror(errno));
                    return -1;
                }
                return 0;
            }
            fprintf(stderr,
                    "Error opening %s: %s\n",
                    loc->path, strerror(errno));
            return -1;
        }
        return 0;
    }
    return -1;
}
コード例 #28
0
SshRadiusUrlStatus
ssh_radius_url_init_avpset(SshRadiusUrlAvpSet set, unsigned char *url)
{

  unsigned char *path, *type;
  const unsigned char *key, *value;
  size_t key_length, value_length;
  SshUrlQuery query;
  const SshRadiusAvpInfoStruct *avp_info;
  SshRadiusUrlStatus url_status;
  SshRadiusUrlStatus bad_url_status;

  url_status = SSH_RADIUS_URL_STATUS_NONE;
  set->avp = NULL;
  set->navps = 0;

  if (url == NULL)
    return SSH_RADIUS_URL_STATUS_SUCCESS;

  path = ssh_radius_get_url_path(url);
  type = NULL;
  query = NULL;

  if (path != NULL && path[0] != '\0')
    {
      if (ssh_url_parse_get(path,
                            NULL, NULL, &type, &query, NULL, FALSE)
          != SSH_URL_OK)
        {
          url_status = SSH_RADIUS_URL_AVPLIST_MALFORMED;
          goto fail;
        }
    }

  if (query != NULL)
    {
      SshUrlEntry entry;

      bad_url_status = SSH_RADIUS_URL_STATUS_NONE;

      for (entry = ssh_url_query_enumerate_start(query);
           entry;
           entry = ssh_url_query_enumerate_next(query, entry))
        {

          key = ssh_url_entry_key(entry, &key_length);
          value = ssh_url_entry_value(entry, &value_length);

          if (key != NULL)
            {
              avp_info = ssh_radius_avp_info_name((char *)key);

              if (avp_info == NULL)
                {
                  SSH_DEBUG(SSH_D_FAIL,
                            ("unrecognized RADIUS attribute name: %s",
                             key));
                  bad_url_status = SSH_RADIUS_URL_UNKNOWN_AVP_TYPE;
                }
              else
                {
                  url_status = ssh_radius_url_add_avp(set, avp_info,
                                                      (unsigned char *) value,
                                                      value_length);
                  if (url_status != SSH_RADIUS_URL_STATUS_SUCCESS)
                    {
                      SSH_DEBUG(SSH_D_FAIL,
                                ("failed to add attribute %s to "
                                 "request",key));
                      bad_url_status = url_status;
                    }
                }
            }
        }

      ssh_url_query_free(query);

      if (bad_url_status != SSH_RADIUS_URL_STATUS_NONE)
        {
          url_status = bad_url_status;
          goto fail;
        }
    }

  if (type != NULL)
    ssh_free(type);

  ssh_free(path);
  return SSH_RADIUS_URL_STATUS_SUCCESS;

 fail:
  if (path != NULL)
    ssh_free(path);

  if (type != NULL)
    ssh_free(type);

  return url_status;
}
コード例 #29
0
SshX509AsyncCallStatus
ssh_x509_crmf_encode_asn1(void *context)
{
    SshX509CertEncodeContext encode_context = context;
    SshAsn1Node crequest, ctemplate;
    SshX509CRMFEncodeCtx crmf_context;
    Boolean have_pop = FALSE;
    SshX509Certificate cert = encode_context->cert;

    /* Encode the templatep. */
    if (encode_context->issuer_key
            || cert->pop.ra_verified
            || cert->pop.this_message
            || cert->pop.subsequent_message
            != SSH_X509_POP_SUBSEQ_UNDEF)
        have_pop = TRUE;

    if (have_pop ||
            cert->controls.node != NULL)
    {
        encode_context->rv =
            ssh_x509_crmf_encode_request(encode_context->asn1_context,
                                         cert,
                                         encode_context->issuer_key,
                                         &crequest);

        if (encode_context->rv != SSH_X509_OK)
            return SSH_X509_ASYNC_CALL_ERROR;

        if ((crmf_context = ssh_calloc(1, sizeof(*crmf_context))) != NULL)
        {
            crmf_context->encode_context = encode_context;
            crmf_context->cert_templatep = crequest;

            if (have_pop)
            {
                /* Handle encoding of the POP. For some methods for proof
                   this also computes the signature. */
                return ssh_x509_pop_encode(crmf_context);
            }
            else
            {
                ssh_x509_crmf_encode_finalize(crmf_context);
                return SSH_X509_ASYNC_CALL_COMPLETED;
            }
        }
        else
            return SSH_X509_ASYNC_CALL_ERROR;
    }
    else
    {
        encode_context->rv =
            ssh_x509_crmf_encode_templatep(encode_context->asn1_context,
                                           cert,
                                           encode_context->issuer_key,
                                           &ctemplate);

        if (encode_context->rv == SSH_X509_OK &&
                (ssh_asn1_encode_node(encode_context->asn1_context, ctemplate))
                == SSH_ASN1_STATUS_OK)
        {
            ssh_asn1_node_get_data(ctemplate,
                                   &(encode_context->buf),
                                   &(encode_context->buf_len));

            if (SSH_X509_CERT_ENCODE_IS_ASYNCHRONOUS(encode_context))
            {
                (*encode_context->user_encode_cb)(encode_context->rv,
                                                  encode_context->buf,
                                                  encode_context->buf_len,
                                                  encode_context->user_context);

                ssh_free(encode_context->buf);
                ssh_operation_abort(encode_context->operation_handle);
            }
        }
        else
        {
            ssh_operation_unregister(encode_context->operation_handle);
            return SSH_X509_ASYNC_CALL_ERROR;
        }
        return SSH_X509_ASYNC_CALL_COMPLETED;
    }
}
コード例 #30
0
ファイル: mock-sshd.c プロジェクト: AmartC/cockpit
static gint
mock_ssh_server (const gchar *server_addr,
                 gint server_port,
                 const gchar *user,
                 const gchar *password)
{
  char portname[16];
  char addrname[16];
  struct sockaddr_storage addr;
  socklen_t addrlen;
  ssh_bind sshbind;
  const char *msg;
  int r;

  state.event = ssh_event_new ();
  if (state.event == NULL)
    g_return_val_if_reached (-1);

  sshbind = ssh_bind_new ();
  state.session = ssh_new ();

  if (server_addr == NULL)
    server_addr = "127.0.0.1";

  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDADDR, server_addr);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDPORT, &server_port);
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_RSAKEY, SRCDIR "/src/ws/mock_rsa_key");
  ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_DSAKEY, SRCDIR "/src/ws/mock_dsa_key");

  if (ssh_bind_listen (sshbind) < 0)
    {
      g_critical ("couldn't listen on socket: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.bind_fd = ssh_bind_get_fd (sshbind);
  state.user = user;
  state.password = password;
  ssh_pki_import_pubkey_file (SRCDIR "/src/ws/test_rsa.pub",
                              &state.pkey);
  state.buffer = g_byte_array_new ();

  /* Print out the port */
  if (server_port == 0)
    {
      addrlen = sizeof (addr);
      if (getsockname (state.bind_fd, (struct sockaddr *)&addr, &addrlen) < 0)
        {
          g_critical ("couldn't get local address: %s", g_strerror (errno));
          return 1;
        }
      r = getnameinfo ((struct sockaddr *)&addr, addrlen, addrname, sizeof (addrname),
                       portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV);
      if (r != 0)
        {
          g_critical ("couldn't get local port: %s", gai_strerror (r));
          return 1;
        }

      /* Caller wants to know the port */
      g_print ("%s\n", portname);
    }

  /* Close stdout (once above info is printed) */
  close (1);

  ssh_set_message_callback (state.session, authenticate_callback, NULL);

  r = ssh_bind_accept (sshbind, state.session);
  if (r == SSH_ERROR)
    {
      g_critical ("accepting connection failed: %s", ssh_get_error (sshbind));
      return 1;
    }

  state.session_fd = ssh_get_fd (state.session);

  if (ssh_handle_key_exchange (state.session))
    {
      msg = ssh_get_error (state.session);
      if (!strstr (msg, "_DISCONNECT"))
        g_critical ("key exchange failed: %s", msg);
      return 1;
    }

  if (ssh_event_add_session (state.event, state.session) != SSH_OK)
    g_return_val_if_reached (-1);

  do
    {
      ssh_event_dopoll (state.event, 10000);
    }
  while (ssh_is_connected (state.session));

  ssh_event_remove_session (state.event, state.session);
  ssh_event_free (state.event);
  ssh_free (state.session);
  ssh_key_free (state.pkey);
  g_byte_array_free (state.buffer, TRUE);
  ssh_bind_free (sshbind);

  return 0;
}