text:
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "kudu/rpc/rpc-test-base.h"

#include <sys/stat.h>
#include <unistd.h>

#include <cstdio>
#include <cstdlib>
#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include <boost/optional/optional.hpp>
#include <gflags/gflags.h>
#include <gflags/gflags_declare.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <sasl/sasl.h>

#include "kudu/gutil/ref_counted.h"
#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/walltime.h"
#include "kudu/rpc/client_negotiation.h"
#include "kudu/rpc/messenger.h"
#include "kudu/rpc/negotiation.h"
#include "kudu/rpc/remote_user.h"
#include "kudu/rpc/sasl_common.h"
#include "kudu/rpc/server_negotiation.h"
#include "kudu/security/cert.h"
#include "kudu/security/crypto.h"
#include "kudu/security/security-test-util.h"
#include "kudu/security/security_flags.h"
#include "kudu/security/test/mini_kdc.h"
#include "kudu/security/tls_context.h"
#include "kudu/security/tls_socket.h"
#include "kudu/security/token.pb.h"
#include "kudu/security/token_signer.h"
#include "kudu/security/token_signing_key.h"
#include "kudu/security/token_verifier.h"
#include "kudu/util/env.h"
#include "kudu/util/monotime.h"
#include "kudu/util/net/sockaddr.h"
#include "kudu/util/net/socket.h"
#include "kudu/util/status.h"
#include "kudu/util/subprocess.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/test_util.h"
#include "kudu/util/trace.h"
#include "kudu/util/user.h"

// HACK: MIT Kerberos doesn't have any way of determining its version number,
// but the error messages in krb5-1.10 and earlier are broken due to
// a bug: http://krbdev.mit.edu/rt/Ticket/Display.html?id=6973
//
// Since we don't have any way to explicitly figure out the version, we just
// look for this random macro which was added in 1.11 (the same version in which
// the above bug was fixed).
#ifndef KRB5_RESPONDER_QUESTION_PASSWORD
#define KRB5_VERSION_LE_1_10
#endif

DEFINE_bool(is_test_child, false,
            "Used by tests which require clean processes. "
            "See TestDisableInit.");
DECLARE_bool(rpc_encrypt_loopback_connections);
DECLARE_bool(rpc_trace_negotiation);

using std::string;
using std::thread;
using std::unique_ptr;
using std::vector;

using kudu::security::Cert;
using kudu::security::PkiConfig;
using kudu::security::PrivateKey;
using kudu::security::SignedTokenPB;
using kudu::security::TlsContext;
using kudu::security::TokenSigner;
using kudu::security::TokenSigningPrivateKey;
using kudu::security::TokenVerifier;

namespace kudu {
namespace rpc {

// The negotiation configuration for a client or server endpoint.
struct EndpointConfig {
  // The PKI configuration.
  PkiConfig pki;
  // The supported SASL mechanisms.
  vector<SaslMechanism::Type> sasl_mechs;
  // For the client, whether the client has the token.
  // For the server, whether the server has the TSK.
  bool token;
  RpcEncryption encryption;
};
std::ostream& operator<<(std::ostream& o, EndpointConfig config) {
  auto bool_string = [] (bool b) { return b ? "true" : "false"; };
  o << "{pki: " << config.pki
    << ", sasl-mechs: [" << JoinMapped(config.sasl_mechs, SaslMechanism::name_of, ", ")
    << "], token: " << bool_string(config.token)
    << ", encryption: ";

  switch (config.encryption) {
    case RpcEncryption::DISABLED: o << "DISABLED"; break;
    case RpcEncryption::OPTIONAL: o << "OPTIONAL"; break;
    case RpcEncryption::REQUIRED: o << "REQUIRED"; break;
  }

  o << "}";
  return o;
}

// A description of a negotiation sequence, including client and server
// configuration, as well as expected results.
struct NegotiationDescriptor {
  EndpointConfig client;
  EndpointConfig server;

  bool use_test_socket;

  bool rpc_encrypt_loopback;

  // The expected client status from negotiating.
  Status client_status;
  // The expected server status from negotiating.
  Status server_status;

  // The expected negotiated authentication type.
  AuthenticationType negotiated_authn;

  // The expected SASL mechanism, if SASL authentication is negotiated.
  SaslMechanism::Type negotiated_mech;

  // Whether the negotiation is expected to perform a TLS handshake.
  bool tls_negotiated;
};
std::ostream& operator<<(std::ostream& o, NegotiationDescriptor c) {
  auto bool_string = [] (bool b) { return b ? "true" : "false"; };
  o << "{client: " << c.client
    << ", server: " << c.server
    << "}, rpc-encrypt-loopback: " << bool_string(c.rpc_encrypt_loopback);
  return o;
}

class NegotiationTestSocket : public Socket {
 public:
  // Return an arbitrary public IP
  Status GetPeerAddress(Sockaddr *cur_addr) const override {
    return cur_addr->ParseString("8.8.8.8:12345", 0);
  }
};

class TestNegotiation : public RpcTestBase,
                        public ::testing::WithParamInterface<NegotiationDescriptor> {
 public:
  void SetUp() override {
    RpcTestBase::SetUp();
    ASSERT_OK(SaslInit());
  }
};

TEST_P(TestNegotiation, TestNegotiation) {
  NegotiationDescriptor desc = GetParam();

  // Generate a trusted root certificate.
  PrivateKey ca_key;
  Cert ca_cert;
  ASSERT_OK(GenerateSelfSignedCAForTests(&ca_key, &ca_cert));

  // Create and configure a TLS context for each endpoint.
  TlsContext client_tls_context;
  TlsContext server_tls_context;
  ASSERT_OK(client_tls_context.Init());
  ASSERT_OK(server_tls_context.Init());
  ASSERT_OK(ConfigureTlsContext(desc.client.pki, ca_cert, ca_key, &client_tls_context));
  ASSERT_OK(ConfigureTlsContext(desc.server.pki, ca_cert, ca_key, &server_tls_context));

  FLAGS_rpc_encrypt_loopback_connections = desc.rpc_encrypt_loopback;

  // Generate an optional client token and server token verifier.
  TokenSigner token_signer(60, 20, std::make_shared<TokenVerifier>());
  {
    unique_ptr<TokenSigningPrivateKey> key;
    ASSERT_OK(token_signer.CheckNeedKey(&key));
    // No keys are available yet, so should be able to add.
    ASSERT_NE(nullptr, key.get());
    ASSERT_OK(token_signer.AddKey(std::move(key)));
  }
  TokenVerifier token_verifier;
  boost::optional<SignedTokenPB> authn_token;
  if (desc.client.token) {
    authn_token = SignedTokenPB();
    security::TokenPB token;
    token.set_expire_unix_epoch_seconds(WallTime_Now() + 60);
    token.mutable_authn()->set_username("client-token");
    ASSERT_TRUE(token.SerializeToString(authn_token->mutable_token_data()));
    ASSERT_OK(token_signer.SignToken(&*authn_token));
  }
  if (desc.server.token) {
    ASSERT_OK(token_verifier.ImportKeys(token_signer.verifier().ExportKeys()));
  }

  // Create the listening socket, client socket, and server socket.
  Socket listening_socket;
  ASSERT_OK(listening_socket.Init(0));
  ASSERT_OK(listening_socket.BindAndListen(Sockaddr(), 1));
  Sockaddr server_addr;
  ASSERT_OK(listening_socket.GetSocketAddress(&server_addr));

  unique_ptr<Socket> client_socket(new Socket());
  ASSERT_OK(client_socket->Init(0));
  client_socket->Connect(server_addr);

  unique_ptr<Socket> server_socket(desc.use_test_socket ?
                                   new NegotiationTestSocket() :
                                   new Socket());

  Sockaddr client_addr;
  CHECK_OK(listening_socket.Accept(server_socket.get(), &client_addr, 0));

  // Create and configure the client and server negotiation instances.
  ClientNegotiation client_negotiation(std::move(client_socket),
                                       &client_tls_context,
                                       authn_token,
                                       desc.client.encryption,
                                       "kudu");
  ServerNegotiation server_negotiation(std::move(server_socket),
                                       &server_tls_context,
                                       &token_verifier,
                                       desc.server.encryption,
                                       "kudu");

  // Set client and server SASL mechanisms.
  MiniKdc kdc;
  bool kdc_started = false;
  auto start_kdc_once = [&] () {
    if (!kdc_started) {
      kdc_started = true;
      RETURN_NOT_OK(kdc.Start());
    }
    return Status::OK();
  };
  for (auto mech : desc.client.sasl_mechs) {
    switch (mech) {
      case SaslMechanism::INVALID: break;
      case SaslMechanism::PLAIN:
        ASSERT_OK(client_negotiation.EnablePlain("client-plain", "client-password"));
        break;
      case SaslMechanism::GSSAPI:
        ASSERT_OK(start_kdc_once());
        ASSERT_OK(kdc.CreateUserPrincipal("client-gssapi"));
        ASSERT_OK(kdc.Kinit("client-gssapi"));
        ASSERT_OK(kdc.SetKrb5Environment());
        client_negotiation.set_server_fqdn("127.0.0.1");
        ASSERT_OK(client_negotiation.EnableGSSAPI());
        break;
    }
  }
  for (auto mech : desc.server.sasl_mechs) {
    switch (mech) {
      case SaslMechanism::INVALID: break;
      case SaslMechanism::PLAIN:
        ASSERT_OK(server_negotiation.EnablePlain());
        break;
      case SaslMechanism::GSSAPI:
        ASSERT_OK(start_kdc_once());
        // Create the server principal and keytab.
        string kt_path;
        ASSERT_OK(kdc.CreateServiceKeytab("kudu/127.0.0.1", &kt_path));
        CHECK_ERR(setenv("KRB5_KTNAME", kt_path.c_str(), 1 /*replace*/));
        server_negotiation.set_server_fqdn("127.0.0.1");
        ASSERT_OK(server_negotiation.EnableGSSAPI());
        break;
    }
  }

  // Run the client/server negotiation. Because negotiation is blocking, it
  // has to be done on separate threads.
  Status client_status;
  Status server_status;
  thread client_thread([&] () {
      scoped_refptr<Trace> t(new Trace());
      ADOPT_TRACE(t.get());
      client_status = client_negotiation.Negotiate();
      // Close the socket so that the server will not block forever on error.
      client_negotiation.socket()->Close();

      if (FLAGS_rpc_trace_negotiation || !client_status.ok()) {
        string msg = Trace::CurrentTrace()->DumpToString();
        if (!client_status.ok()) {
          LOG(WARNING) << "Failed client RPC negotiation. Client trace:\n" << msg;
        } else {
          LOG(INFO) << "RPC negotiation tracing enabled. Client trace:\n" << msg;
        }
      }
  });
  thread server_thread([&] () {
      scoped_refptr<Trace> t(new Trace());
      ADOPT_TRACE(t.get());
      server_status = server_negotiation.Negotiate();
      // Close the socket so that the client will not block forever on error.
      server_negotiation.socket()->Close();

      if (FLAGS_rpc_trace_negotiation || !server_status.ok()) {
        string msg = Trace::CurrentTrace()->DumpToString();
        if (!server_status.ok()) {
          LOG(WARNING) << "Failed server RPC negotiation. Server trace:\n" << msg;
        } else {
          LOG(INFO) << "RPC negotiation tracing enabled. Server trace:\n" << msg;
        }
      }
  });
  client_thread.join();
  server_thread.join();

  // Check the negotiation outcome against the expected outcome.
  EXPECT_EQ(desc.client_status.CodeAsString(), client_status.CodeAsString());
  EXPECT_EQ(desc.server_status.CodeAsString(), server_status.CodeAsString());
  ASSERT_STR_MATCHES(client_status.ToString(), desc.client_status.ToString());
  ASSERT_STR_MATCHES(server_status.ToString(), desc.server_status.ToString());

  if (client_status.ok()) {
    EXPECT_TRUE(server_status.ok());

    // Make sure the negotiations agree with the expected values.
    EXPECT_EQ(desc.negotiated_authn, client_negotiation.negotiated_authn());
    EXPECT_EQ(desc.negotiated_mech, client_negotiation.negotiated_mechanism());
    EXPECT_EQ(desc.negotiated_authn, server_negotiation.negotiated_authn());
    EXPECT_EQ(desc.negotiated_mech, server_negotiation.negotiated_mechanism());
    EXPECT_EQ(desc.tls_negotiated, server_negotiation.tls_negotiated());
    EXPECT_EQ(desc.tls_negotiated, server_negotiation.tls_negotiated());

    bool client_tls_socket = dynamic_cast<security::TlsSocket*>(client_negotiation.socket());
    bool server_tls_socket = dynamic_cast<security::TlsSocket*>(server_negotiation.socket());
    EXPECT_EQ(desc.rpc_encrypt_loopback, client_tls_socket);
    EXPECT_EQ(desc.rpc_encrypt_loopback, server_tls_socket);

    // Check that the expected user subject is authenticated.
    RemoteUser remote_user = server_negotiation.take_authenticated_user();
    switch (server_negotiation.negotiated_authn()) {
      case AuthenticationType::SASL:
        switch (server_negotiation.negotiated_mechanism()) {
          case SaslMechanism::PLAIN:
            EXPECT_EQ("client-plain", remote_user.username());
            break;
          case SaslMechanism::GSSAPI:
            EXPECT_EQ("client-gssapi", remote_user.username());
            EXPECT_EQ("client-gssapi@KRBTEST.COM", remote_user.principal().value_or(""));
            break;
          case SaslMechanism::INVALID: LOG(FATAL) << "invalid mechanism negotiated";
        }
        break;
      case AuthenticationType::CERTIFICATE: {
        // We expect the cert to be using the local username, because it hasn't
        // logged in from any Keytab.
        string expected;
        CHECK_OK(GetLoggedInUser(&expected));
        EXPECT_EQ(expected, remote_user.username());
        EXPECT_FALSE(remote_user.principal());
        break;
      }
      case AuthenticationType::TOKEN:
        EXPECT_EQ("client-token", remote_user.username());
        break;
      case AuthenticationType::INVALID: LOG(FATAL) << "invalid authentication negotiated";
    }
  }
}

INSTANTIATE_TEST_CASE_P(NegotiationCombinations,
                        TestNegotiation,
                        ::testing::Values(

        // client: no authn/mechs
        // server: no authn/mechs
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            {},
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            {},
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::NotAuthorized(".*client is not configured with an authentication type"),
          Status::NetworkError(""),
          AuthenticationType::INVALID,
          SaslMechanism::INVALID,
          false,
        },

        // client: PLAIN
        // server: no authn/mechs
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            {},
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::NotAuthorized(".* server mechanism list is empty"),
          Status::NotAuthorized(".* server mechanism list is empty"),
          AuthenticationType::INVALID,
          SaslMechanism::INVALID,
          false,
        },

        // client: PLAIN
        // server: PLAIN
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL
          },
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          false,
        },

        // client: GSSAPI
        // server: GSSAPI
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          false,
        },

        // client: GSSAPI, PLAIN
        // server: GSSAPI, PLAIN
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI, SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI, SaslMechanism::PLAIN },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          false,
        },

        // client: GSSAPI, PLAIN
        // server: GSSAPI
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI, SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          false,
        },

        // client: PLAIN
        // server: GSSAPI
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::NotAuthorized(".*client does not have Kerberos credentials available"),
          Status::NetworkError(""),
          AuthenticationType::INVALID,
          SaslMechanism::INVALID,
          false,
        },

        // client: GSSAPI,
        // server: GSSAPI, self-signed cert
        // loopback encryption
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SELF_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          true,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: GSSAPI, signed-cert
        // server: GSSAPI, self-signed cert
        // This tests that the server will not advertise CERTIFICATE authentication,
        // since it doesn't have a trusted cert.
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SELF_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: PLAIN,
        // server: PLAIN, self-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SELF_SIGNED,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          true,
        },

        // client: signed-cert
        // server: signed-cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::CERTIFICATE,
          SaslMechanism::INVALID,
          true,
        },

        // client: token, trusted cert
        // server: token, signed-cert, GSSAPI
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::TRUSTED,
            { },
            true,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN },
            true,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::TOKEN,
          SaslMechanism::INVALID,
          true,
        },

        // client: PLAIN, token
        // server: PLAIN, token, signed cert
        // Test that the client won't negotiate token authn if it doesn't have a
        // trusted cert. We aren't expecting this to happen in practice (the
        // token and trusted CA cert should come as a package).
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            true,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN },
            true,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          true,
        },

        // client: PLAIN, GSSAPI, signed-cert, token
        // server: PLAIN, GSSAPI, signed-cert, token
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN, SaslMechanism::GSSAPI },
            true,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN, SaslMechanism::GSSAPI },
            true,
            RpcEncryption::OPTIONAL,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::CERTIFICATE,
          SaslMechanism::INVALID,
          true,
        },

        // client: PLAIN, TLS disabled
        // server: PLAIN, TLS required
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::DISABLED,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::NotAuthorized(".*client does not support required TLS encryption"),
          Status::NotAuthorized(".*client does not support required TLS encryption"),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          true,
        },

        // client: PLAIN, TLS required
        // server: PLAIN, TLS disabled
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::REQUIRED,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::DISABLED,
          },
          false,
          false,
          Status::NotAuthorized(".*server does not support required TLS encryption"),
          Status::NetworkError(""),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          true,
        },

        // client: GSSAPI, TLS required, externally-signed cert
        // server: GSSAPI, TLS required, externally-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: GSSAPI, TLS optional, externally-signed cert
        // server: GSSAPI, TLS required, signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::OPTIONAL,
          },
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: GSSAPI, TLS required
        // server: GSSAPI, TLS required, externally-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::NONE,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: GSSAPI, PLAIN, TLS required, externally-signed cert
        // server: PLAIN, TLS required, externally-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI, SaslMechanism::PLAIN },
            false,
            RpcEncryption::REQUIRED,
          },
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::PLAIN },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::PLAIN,
          true,
        },

        // client: GSSAPI, TLS disabled, signed cert
        // server: GSSAPI, TLS required, externally-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::DISABLED,
          },
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::NotAuthorized(".*client does not support required TLS encryption"),
          Status::NotAuthorized(".*client does not support required TLS encryption"),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: GSSAPI, TLS required, signed cert
        // server: GSSAPI, TLS required, externally-signed cert
        NegotiationDescriptor {
          EndpointConfig {
            PkiConfig::SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          EndpointConfig {
            PkiConfig::EXTERNALLY_SIGNED,
            { SaslMechanism::GSSAPI },
            false,
            RpcEncryption::REQUIRED,
          },
          false,
          false,
          Status::OK(),
          Status::OK(),
          AuthenticationType::SASL,
          SaslMechanism::GSSAPI,
          true,
        },

        // client: PLAIN
        // server: PLAIN
        // connection from public routable IP
        NegotiationDescriptor {
            EndpointConfig {
                PkiConfig::NONE,
                { SaslMechanism::PLAIN },
                false,
                RpcEncryption::OPTIONAL
            },
            EndpointConfig {
                PkiConfig::NONE,
                { SaslMechanism::PLAIN },
                false,
                RpcEncryption::OPTIONAL
            },
            true,
            false,
            Status::NotAuthorized(".*unencrypted connections from publicly routable IPs"),
            Status::NotAuthorized(".*unencrypted connections from publicly routable IPs"),
            AuthenticationType::SASL,
            SaslMechanism::PLAIN,
            false,
        },

        // client: GSSAPI, TLS required, externally-signed cert
        // server: GSSAPI, TLS required, externally-signed cert
        // connection from public routable IP
        NegotiationDescriptor {
            EndpointConfig {
                PkiConfig::EXTERNALLY_SIGNED,
                { SaslMechanism::GSSAPI },
                false,
                RpcEncryption::REQUIRED,
            },
            EndpointConfig {
                PkiConfig::EXTERNALLY_SIGNED,
                { SaslMechanism::GSSAPI },
                false,
                RpcEncryption::REQUIRED,
            },
            true,
            // true as no longer a loopback connection.
            true,
            Status::OK(),
            Status::OK(),
            AuthenticationType::SASL,
            SaslMechanism::GSSAPI,
            true,
        }
));

// A "Callable" that takes a socket for use with starting a thread.
// Can be used for ServerNegotiation or ClientNegotiation threads.
typedef std::function<void(unique_ptr<Socket>)> SocketCallable;

// Call Accept() on the socket, then pass the connection to the server runner
static void RunAcceptingDelegator(Socket* acceptor,
                                  const SocketCallable& server_runner) {
  unique_ptr<Socket> conn(new Socket());
  Sockaddr remote;
  CHECK_OK(acceptor->Accept(conn.get(), &remote, 0));
  server_runner(std::move(conn));
}

// Set up a socket and run a negotiation sequence.
static void RunNegotiationTest(const SocketCallable& server_runner,
                               const SocketCallable& client_runner) {
  Socket server_sock;
  CHECK_OK(server_sock.Init(0));
  ASSERT_OK(server_sock.BindAndListen(Sockaddr(), 1));
  Sockaddr server_bind_addr;
  ASSERT_OK(server_sock.GetSocketAddress(&server_bind_addr));
  thread server(RunAcceptingDelegator, &server_sock, server_runner);

  unique_ptr<Socket> client_sock(new Socket());
  CHECK_OK(client_sock->Init(0));
  ASSERT_OK(client_sock->Connect(server_bind_addr));
  thread client(client_runner, std::move(client_sock));

  LOG(INFO) << "Waiting for test threads to terminate...";
  client.join();
  LOG(INFO) << "Client thread terminated.";

  server.join();
  LOG(INFO) << "Server thread terminated.";
}

////////////////////////////////////////////////////////////////////////////////

#ifndef __APPLE__
template<class T>
using CheckerFunction = std::function<void(const Status&, T&)>;

// Run GSSAPI negotiation from the server side. Runs
// 'post_check' after negotiation to verify the result.
static void RunGSSAPINegotiationServer(unique_ptr<Socket> socket,
                                       const CheckerFunction<ServerNegotiation>& post_check) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  TokenVerifier token_verifier;
  ServerNegotiation server_negotiation(std::move(socket), &tls_context,
                                       &token_verifier, RpcEncryption::OPTIONAL, "kudu");
  server_negotiation.set_server_fqdn("127.0.0.1");
  CHECK_OK(server_negotiation.EnableGSSAPI());
  post_check(server_negotiation.Negotiate(), server_negotiation);
}

// Run GSSAPI negotiation from the client side. Runs
// 'post_check' after negotiation to verify the result.
static void RunGSSAPINegotiationClient(unique_ptr<Socket> conn,
                                       const CheckerFunction<ClientNegotiation>& post_check) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  ClientNegotiation client_negotiation(std::move(conn), &tls_context,
                                       boost::none, RpcEncryption::OPTIONAL, "kudu");
  client_negotiation.set_server_fqdn("127.0.0.1");
  CHECK_OK(client_negotiation.EnableGSSAPI());
  post_check(client_negotiation.Negotiate(), client_negotiation);
}

// Test invalid SASL negotiations using the GSSAPI (kerberos) mechanism over a socket.
// This test is ignored on macOS because the system Kerberos implementation
// (Heimdal) caches the non-existence of client credentials, which causes futher
// tests to fail.
TEST_F(TestNegotiation, TestGSSAPIInvalidNegotiation) {
  MiniKdc kdc;
  ASSERT_OK(kdc.Start());

  // Try to negotiate with no krb5 credentials on either side. It should fail on both
  // sides.
  RunNegotiationTest(
      std::bind(RunGSSAPINegotiationServer, std::placeholders::_1,
                [](const Status& s, ServerNegotiation& server) {
                  // The client notices there are no credentials and
                  // doesn't send any failure message to the server.
                  // Instead, it just disconnects.
                  //
                  // TODO(todd): it might be preferable to have the server
                  // fail to start if it has no valid keytab.
                  CHECK(s.IsNetworkError());
                }),
      std::bind(RunGSSAPINegotiationClient, std::placeholders::_1,
                [](const Status& s, ClientNegotiation& client) {
                  CHECK(s.IsNotAuthorized());
#ifndef KRB5_VERSION_LE_1_10
                  CHECK_GT(s.ToString().find("No Kerberos credentials available"), 0);
#endif
                }));

  // Create the server principal and keytab.
  string kt_path;
  ASSERT_OK(kdc.CreateServiceKeytab("kudu/127.0.0.1", &kt_path));
  CHECK_ERR(setenv("KRB5_KTNAME", kt_path.c_str(), 1 /*replace*/));

  // Try to negotiate with no krb5 credentials on the client. It should fail on both
  // sides.
  RunNegotiationTest(
      std::bind(RunGSSAPINegotiationServer, std::placeholders::_1,
                [](const Status& s, ServerNegotiation& server) {
                  // The client notices there are no credentials and
                  // doesn't send any failure message to the server.
                  // Instead, it just disconnects.
                  CHECK(s.IsNetworkError());
                }),
      std::bind(RunGSSAPINegotiationClient, std::placeholders::_1,
                [](const Status& s, ClientNegotiation& client) {
                  CHECK(s.IsNotAuthorized());
                  ASSERT_STR_MATCHES(s.ToString(),
                                     "Not authorized: server requires authentication, "
                                     "but client does not have Kerberos credentials available");
                }));

  // Create and kinit as a client user.
  ASSERT_OK(kdc.CreateUserPrincipal("testuser"));
  ASSERT_OK(kdc.Kinit("testuser"));
  ASSERT_OK(kdc.SetKrb5Environment());

  // Change the server's keytab file so that it has inappropriate
  // credentials.
  // Authentication should now fail.
  ASSERT_OK(kdc.CreateServiceKeytab("otherservice/127.0.0.1", &kt_path));
  CHECK_ERR(setenv("KRB5_KTNAME", kt_path.c_str(), 1 /*replace*/));

  RunNegotiationTest(
      std::bind(RunGSSAPINegotiationServer, std::placeholders::_1,
                [](const Status& s, ServerNegotiation& server) {
                  CHECK(s.IsNotAuthorized());
#ifndef KRB5_VERSION_LE_1_10
                  ASSERT_STR_CONTAINS(s.ToString(),
                                      "No key table entry found matching kudu/127.0.0.1");
#endif
                }),
      std::bind(RunGSSAPINegotiationClient, std::placeholders::_1,
                [](const Status& s, ClientNegotiation& client) {
                  CHECK(s.IsNotAuthorized());
#ifndef KRB5_VERSION_LE_1_10
                  ASSERT_STR_CONTAINS(s.ToString(),
                                      "No key table entry found matching kudu/127.0.0.1");
#endif
                }));
}
#endif

#ifndef __APPLE__
// Test that the pre-flight check for servers requiring Kerberos provides
// nice error messages for missing or bad keytabs.
//
// This is ignored on macOS because the system Kerberos implementation does not
// fail the preflight check when the keytab is inaccessible, probably because
// the preflight check passes a 0-length token.
TEST_F(TestNegotiation, TestPreflight) {
  // Try pre-flight with no keytab.
  Status s = ServerNegotiation::PreflightCheckGSSAPI("kudu");
  ASSERT_FALSE(s.ok());
#ifndef KRB5_VERSION_LE_1_10
  ASSERT_STR_MATCHES(s.ToString(), "Key table file.*not found");
#endif
  // Try with a valid krb5 environment and keytab.
  MiniKdc kdc;
  ASSERT_OK(kdc.Start());
  ASSERT_OK(kdc.SetKrb5Environment());
  string kt_path;
  ASSERT_OK(kdc.CreateServiceKeytab("kudu/127.0.0.1", &kt_path));
  CHECK_ERR(setenv("KRB5_KTNAME", kt_path.c_str(), 1 /*replace*/));

  ASSERT_OK(ServerNegotiation::PreflightCheckGSSAPI("kudu"));

  // Try with an inaccessible keytab.
  CHECK_ERR(chmod(kt_path.c_str(), 0000));
  s = ServerNegotiation::PreflightCheckGSSAPI("kudu");
  ASSERT_FALSE(s.ok());
#ifndef KRB5_VERSION_LE_1_10
  ASSERT_STR_MATCHES(s.ToString(), "error accessing keytab: Permission denied");
#endif
  CHECK_ERR(unlink(kt_path.c_str()));

  // Try with a keytab that has the wrong credentials.
  ASSERT_OK(kdc.CreateServiceKeytab("wrong-service/127.0.0.1", &kt_path));
  CHECK_ERR(setenv("KRB5_KTNAME", kt_path.c_str(), 1 /*replace*/));
  s = ServerNegotiation::PreflightCheckGSSAPI("kudu");
  ASSERT_FALSE(s.ok());
#ifndef KRB5_VERSION_LE_1_10
  ASSERT_STR_MATCHES(s.ToString(), "No key table entry found matching kudu/.*");
#endif
}
#endif

////////////////////////////////////////////////////////////////////////////////

static void RunTimeoutExpectingServer(unique_ptr<Socket> socket) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  TokenVerifier token_verifier;
  ServerNegotiation server_negotiation(std::move(socket), &tls_context,
                                       &token_verifier, RpcEncryption::OPTIONAL, "kudu");
  CHECK_OK(server_negotiation.EnablePlain());
  Status s = server_negotiation.Negotiate();
  ASSERT_TRUE(s.IsNetworkError()) << "Expected client to time out and close the connection. Got: "
                                  << s.ToString();
}

static void RunTimeoutNegotiationClient(unique_ptr<Socket> sock) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  ClientNegotiation client_negotiation(std::move(sock), &tls_context,
                                       boost::none, RpcEncryption::OPTIONAL, "kudu");
  CHECK_OK(client_negotiation.EnablePlain("test", "test"));
  MonoTime deadline = MonoTime::Now() - MonoDelta::FromMilliseconds(100L);
  client_negotiation.set_deadline(deadline);
  Status s = client_negotiation.Negotiate();
  ASSERT_TRUE(s.IsTimedOut()) << "Expected timeout! Got: " << s.ToString();
  CHECK_OK(client_negotiation.socket()->Shutdown(true, true));
}

// Ensure that the client times out.
TEST_F(TestNegotiation, TestClientTimeout) {
  RunNegotiationTest(RunTimeoutExpectingServer, RunTimeoutNegotiationClient);
}

////////////////////////////////////////////////////////////////////////////////

static void RunTimeoutNegotiationServer(unique_ptr<Socket> socket) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  TokenVerifier token_verifier;
  ServerNegotiation server_negotiation(std::move(socket), &tls_context,
                                       &token_verifier, RpcEncryption::OPTIONAL, "kudu");
  CHECK_OK(server_negotiation.EnablePlain());
  MonoTime deadline = MonoTime::Now() - MonoDelta::FromMilliseconds(100L);
  server_negotiation.set_deadline(deadline);
  Status s = server_negotiation.Negotiate();
  ASSERT_TRUE(s.IsTimedOut()) << "Expected timeout! Got: " << s.ToString();
  CHECK_OK(server_negotiation.socket()->Close());
}

static void RunTimeoutExpectingClient(unique_ptr<Socket> socket) {
  TlsContext tls_context;
  CHECK_OK(tls_context.Init());
  ClientNegotiation client_negotiation(std::move(socket), &tls_context,
                                       boost::none, RpcEncryption::OPTIONAL, "kudu");
  CHECK_OK(client_negotiation.EnablePlain("test", "test"));
  Status s = client_negotiation.Negotiate();
  ASSERT_TRUE(s.IsNetworkError()) << "Expected server to time out and close the connection. Got: "
      << s.ToString();
}

// Ensure that the server times out.
TEST_F(TestNegotiation, TestServerTimeout) {
  RunNegotiationTest(RunTimeoutNegotiationServer, RunTimeoutExpectingClient);
}

////////////////////////////////////////////////////////////////////////////////

// This suite of tests ensure that applications that embed the Kudu client are
// able to externally handle the initialization of SASL. See KUDU-1749 and
// IMPALA-4497 for context.
//
// The tests are a bit tricky because the initialization of SASL is static state
// that we can't easily clear/reset between test cases. So, each test invokes
// itself as a subprocess with the appropriate --gtest_filter line as well as a
// special flag to indicate that it is the test child running.
class TestDisableInit : public KuduTest {
 protected:
  // Run the lambda 'f' in a newly-started process, capturing its stderr
  // into 'stderr'.
  template<class TestFunc>
  void DoTest(const TestFunc& f, string* stderr = nullptr) {
    if (FLAGS_is_test_child) {
      f();
      return;
    }

    // Invoke the currently-running test case in a new subprocess.
    string filter_flag = strings::Substitute("--gtest_filter=$0.$1",
                                             CURRENT_TEST_CASE_NAME(), CURRENT_TEST_NAME());
    string executable_path;
    CHECK_OK(env_->GetExecutablePath(&executable_path));
    string stdout;
    Status s = Subprocess::Call({ executable_path, "test", filter_flag, "--is_test_child" },
                                "" /* stdin */,
                                &stdout,
                                stderr);
    ASSERT_TRUE(s.ok()) << "Test failed: " << stdout;
  }
};

// Test disabling SASL but not actually properly initializing it before usage.
TEST_F(TestDisableInit, TestDisableSasl_NotInitialized) {
  DoTest([]() {
      CHECK_OK(DisableSaslInitialization());
      Status s = SaslInit();
      ASSERT_STR_CONTAINS(s.ToString(), "was disabled, but SASL was not externally initialized");
    });
}

// Test disabling SASL with proper initialization by some other app.
TEST_F(TestDisableInit, TestDisableSasl_Good) {
  DoTest([]() {
      rpc::internal::SaslSetMutex();
      sasl_client_init(NULL);
      CHECK_OK(DisableSaslInitialization());
      ASSERT_OK(SaslInit());
    });
}

// Test a client which inits SASL itself but doesn't remember to disable Kudu's
// SASL initialization.
TEST_F(TestDisableInit, TestMultipleSaslInit) {
  string stderr;
  DoTest([]() {
      rpc::internal::SaslSetMutex();
      sasl_client_init(NULL);
      ASSERT_OK(SaslInit());
    }, &stderr);
  // If we are the parent, we should see the warning from the child that it automatically
  // skipped initialization because it detected that it was already initialized.
  if (!FLAGS_is_test_child) {
    ASSERT_STR_CONTAINS(stderr, "Skipping initialization");
  }
}

// We are not able to detect mutexes not being set with the macOS version of libsasl.
#ifndef __APPLE__
// Test disabling SASL but not remembering to initialize the SASL mutex support. This
// should succeed but generate a warning.
TEST_F(TestDisableInit, TestDisableSasl_NoMutexImpl) {
  string stderr;
  DoTest([]() {
      sasl_client_init(NULL);
      CHECK_OK(DisableSaslInitialization());
      ASSERT_OK(SaslInit());
    }, &stderr);
  // If we are the parent, we should see the warning from the child.
  if (!FLAGS_is_test_child) {
    ASSERT_STR_CONTAINS(stderr, "not provided with a mutex implementation");
  }
}

// Test a client which inits SASL itself but doesn't remember to disable Kudu's
// SASL initialization.
TEST_F(TestDisableInit, TestMultipleSaslInit_NoMutexImpl) {
  string stderr;
  DoTest([]() {
      sasl_client_init(NULL);
      ASSERT_OK(SaslInit());
    }, &stderr);
  // If we are the parent, we should see the warning from the child that it automatically
  // skipped initialization because it detected that it was already initialized.
  if (!FLAGS_is_test_child) {
    ASSERT_STR_CONTAINS(stderr, "Skipping initialization");
    ASSERT_STR_CONTAINS(stderr, "not provided with a mutex implementation");
  }
}
#endif

} // namespace rpc
} // namespace kudu

redpajama_set_name: RedPajamaGithub


text:
Angus MacGyver  est le personnage principal des séries MacGyver (diffusée entre 1985 et 1992) et MacGyver (diffusée depuis 2016). Intelligent et optimiste, il préfère régler les conflits de manière non violente. À la suite de la mort accidentelle d'un ami dans sa jeunesse, avec un revolver, il se refuse à utiliser des armes à feu.

Le personnage, interprété par Richard Dean Anderson dans la série originale et par Lucas Till dans le reboot, est présenté comme un militant anti-armes, engagé sur différents thèmes comme la préservation de l'environnement, l'égalité raciale et l'assistance aux personnes défavorisées. Dans les cas où ses bricolages sont utilisés pour attaquer ses ennemis, MacGyver le fait pour se défendre et essaie, autant que possible, de les neutraliser plutôt que de les tuer. Il est souvent suspecté d'avoir un lien militaire avec le gouvernement, mais il voit son travail à la Fondation Phoenix comme une solution alternative et non violente à l'application de la loi.

Son enfance
Angus MacGyver est né dans le Minnesota, le , dans la petite ville de Mission City.

Très jeune, il manifeste un don exceptionnel pour le bricolage, construisant, par exemple, un piège à rats qui ne les tuait pas (ce qui lui permettait de les relâcher ensuite), et réparant la tondeuse à gazon d'un sergent de police, alors que tout le monde lui conseillait de la jeter à la casse.

En 1961, alors qu'il n'a que dix ans, sa grand-mère et son père sont tués dans un accident de voiture dans lequel ils se sont noyés, et MacGyver grandit donc avec sa mère. Son grand-père, Harry Jackson (joué par l'acteur John Anderson), agit comme son père. Mais il s'en éloigne en 1967, quand MacGyver atteint seize ans, pour aller travailler en Alaska, et envoyer de l'argent à MacGyver et sa mère. Finalement, il s'installe comme fermier dans le Minnesota après que MacGyver a décidé de quitter le Minnesota.

MacGyver, que tout le monde appelle par son nom de famille, alors que tous ses amis sont appelés par leurs prénoms, fait partie d'une sympathique « bande des quatre ». MacGyver, Jessie, Neal et Chuck sont inséparables et se font de grandes promesses, comme celle de se retrouver vingt ans plus tard au pied d'un arbre où ils ont enterré une boite avec leurs trésors. Un jour, les quatre amis, « les meilleurs copains du monde », décident de collecter de l'argent pour acheter un pistolet et des balles. En fait, ils veulent agir comme des héros de western en tirant sur des bouteilles vides. Une fois l'argent réuni, ils se retrouvent dans une forêt à l'écart de la route et chargent l'arme. MacGyver tire le premier et toucha sa cible du premier coup, expliquant qu'il s'était déjà entraîné avec son père. Mais lorsqu'un de ses amis, plutôt que de tirer sur une bouteille vide, préfère viser un oiseau, MacGyver veut l'en empêcher. Il donne un coup dans le pistolet qui s'envole. Lorsqu'il retombe à terre, le coup de feu part, blessant grièvement Jessie. Voyant cela, Neal et Chuck s'enfuient. MacGyver, lui, reste auprès de son ami. Pour l'amener sur la grande route, il démonte son vélo et le transforme en brancard. Sur la route, il arrête un automobiliste qui part chercher une ambulance. Celle-ci arrive trop tard. Jessie est mort. MacGyver se promet alors de ne plus jamais se servir d'une arme à feu. Neal et Chuck ne tiennent pas cette promesse puisque le premier devient policier et le second marchand d'armes.

Durant son enfance, il rencontre également Jack Dalton. Quand MacGyver atteint l'âge de dix-neuf ans, sa mère meurt après une brève maladie, alors qu'il est en mission (il ne pourra d'ailleurs pas assister à ses funérailles).

Sa famille
 Son père : James MacGyver
 Sa mère : Ellen Jackson
 Son grand-père : Harry Jackson
 Sa grand-mère : Célia Jackson
 Son fils : Sean Angus Malloy
 La mère de son fils : Kate Malloy
 Son neveu : Clay MacGyver
 Ses ancêtres : Ian MacGyver (), Angus MacGyver (), Ian MacIver (), Angus MacIver (), Ian M'Iver (), Angus M'Iver ().

À l'âge de 10 ans, MacGyver perd son père et sa grand-mère. Ils meurent noyés après une chute accidentelle de leur voiture dans un canal. Il est alors élevé par son grand-père Harry et sa mère Ellen.

À l'âge de 20 ans, MacGyver est en mission en Afghanistan. C'est alors que sa mère meurt d'une crise cardiaque. Il n'assistera pas à ses funérailles et s'en voudra pendant des années.

En 1990, son grand-père meurt d'une crise cardiaque lors d'une partie de pêche. MacGyver est alors âgé de 39 ans.

Sa scolarité
MacGyver a un Bachelor's degree (équivalent en France d'un diplôme entre la licence et le master, soit bac +4) en physique à la fictive Western Tech où, en 1973, un MacGyver moustachu étudiait avec le professeur Julian Ryam, Prix Nobel de physique. Cet homme, qui avait la faculté de tout réparer avec des objets de tous les jours, ayant probablement beaucoup influencé et inspiré MacGyver, instaura dans cette université le concours de barricade (le but est d'inventer un système de fermeture de portes qui tienne le plus longtemps possible face aux assauts des autres candidats) que MacGyver gagna en 1973.

MacGyver parle plus ou moins le français, l'allemand, l'italien, le russe et la langue des signes américaine. Il connaît également le morse, le code des signaux maritimes.

Son travail
Après avoir obtenu son Bachelor's degree, MacGyver refuse une offre de travail à la centrale nucléaire située à proximité. Peu après, il sert durant la guerre du Viêt Nam dans une équipe de déminage.

Finalement, il déménage à Los Angeles où il exerce un certain nombre d'emplois différents, y compris le travail de chauffeur de taxi pour aider son ami Jack Dalton, jusqu'en 1979. À cette date, il rencontre Peter Thornton, un agent du ministère des Services Extérieurs (DXS). Il conserve ce poste jusqu'en 1986 quand Peter Thornton lui offre un emploi à la Fondation Phoenix.

MacGyver travaille alors à la Fondation Phoenix au département des services externes. Son numéro de matricule est DXSID N°XC4479. La Fondation Phoenix est une société privée à but non lucratif qui étend ses activités à des domaines différents tels que l'écologie, l'aide à l'enfance en difficulté, la lutte contre les trafiquants de drogue, la lutte contre les armes nucléaires. MacGyver travaille pour la Fondation durant six ans, avant de la quitter définitivement en 1992, lorsqu'il retrouve son fils.

MacGyver est aussi passionné des causes sociales. En effet, il s'est à plusieurs reprises porté volontaire pour aider les plus défavorisés, par exemple, lorsqu'il dirige la recherche dans une école pour enfants sourds, et qu'il contribue à une excursion en montagne pour de jeunes délinquants.

Ses loisirs
MacGyver est un passionné de hockey, sport qu'il pratique régulièrement depuis son enfance. Il aurait même pu devenir professionnel, mais il a décidé finalement de ne pas le devenir. Ce choix n'empêche pas MacGyver de soutenir l'équipe des Flames de Calgary. Il est aussi intéressé par l'escalade en montagne (malgré son vertige) et le ski.

Lieux d'habitation
MacGyver a eu cinq logements différents :
 un vaste appartement situé dans un laboratoire ;
 un autre appartement se situant à Venice au bord de mer à l'extrémité ouest de Los Angeles cet appartement étant installé au-dessus d'un café ;
 un autre appartement situé à trois kilomètres de l'océan toujours à l'étage mais cette fois situé au-dessus d'un pressing et d'un réparateur de chaussures ;
 une péniche transformée et agrandie située dans un port ;
 le dernier logement de MacGyver, dans la saison 7, est un appartement dans un quartier haïtien, il aidera même les habitants du quartier à lutter contre un prêtre vaudou qui les terrorise.

Caractère
Un des aspects les plus importants de la série est que MacGyver, quand il tente de se protéger ou de défendre quelqu'un, est l'homme « qui ne laisse jamais tomber », et « quand le plan A ne fonctionne pas » pense à un « plan B ». Il y a assez peu d'épisodes où il a besoin d'un « plan B », ce qui est ironique, car Jack O'Neill, joué par le même acteur dans StarGate SG-1, déclare que leurs plans A ne fonctionnent jamais.

Il est aussi très différent des héros stéréotypes « macho » ou stoïques ; pas seulement parce qu'il n'aime pas la violence ni les armes à feu depuis l'accident qui tua l'un de ses amis lorsqu'il était jeune, mais aussi parce qu'il n'hésite pas à montrer qu'il a peur dans des situations périlleuses (lorsqu'il réfléchit à un « plan A » ou que celui-ci ne fonctionne pas par exemple). Il ne cherche pas non plus à cacher qu'il s'est fait mal en donnant des coups de poing dans les bagarres (il pousse traditionnellement un petit cri et se masse le poing après le coup). Ces réactions de « monsieur tout le monde » aident à humaniser le personnage et le rendent ainsi bien plus accessible.

MacGyver fait preuve d'un humour très ironique. Il peut parfois être dur quand il n'apprécie pas quelqu'un. Mais il a bon cœur. C'est ainsi qu'il se laisse à chaque fois embarquer dans des aventures rocambolesques par son ami Jack Dalton.

Son prénom
Le prénom pour MacGyver qui est prévu lors du pilote était Stace : il n'a jamais été utilisé en dehors des dossiers de presse.

Un mystère a longtemps plané sur le véritable prénom de MacGyver, qui se fait appeler « Mac » par ses amis, et ne sera révélé que dans les derniers épisodes.
En effet, son prénom est enfin révélé canoniquement dans l'épisode MacGyver le preux, dans lequel il admet partager le prénom d'un de ses ancêtres du , « Angus » M'Iver.
Dans l'avant dernier épisode, qui introduit le fils de MacGyver, ce dernier porte en deuxième prénom celui de son père. Lors de cet épisode, qui devait clore la série, père et fils partent ensemble à moto, pendant que la voix de MacGyver remercie les spectateurs de leur fidélité.

Version alternative

Références

Personnage de MacGyver
Personnage de fiction du Minnesota
Aventurier de fiction
Vétéran du Viêt Nam de fiction
Agent secret ou espion de fiction
Inventeur de fiction
Personnage de fiction créé en 1985

redpajama_set_name: RedPajamaWikipedia


text:
Neuhardenberg (fino al 1814 Quilitz; dal 1946 al 1990 Marxwalde) è un comune di  abitanti  del Brandeburgo, in Germania.

Appartiene al circondario del Märkisch-Oderland ed è capoluogo dell'Amt Neuhardenberg.

Storia
Il paese, originariamente denominato «Quilitz», venne citato in un documento per la prima volta nel 1348.

Il paese venne semidistrutto da un grande incendio nel 1801, e ricostruito due anni dopo secondo un piano urbanistico elaborato da Karl Friedrich Schinkel.

Nel 1814 l'intero paese divenne proprietà del cancelliere Hardenberg, che decise di ribattezzarlo con il nome di «Neuhardenberg» (letteralmente: «Hardenberg nuova»). Nei decenni successivi, grazie agli interventi della famiglia Hardenberg, il paese si trasformò in un centro importante di produzione agricola.

Nell'autunno 1945, la riforma agraria introdotta dall'occupante sovietico portò all'esproprio forzato delle proprietà terriere della famiglia Hardenberg.

Nel 1949, alla fondazione della Repubblica Democratica Tedesca, alcuni comunisti del luogo presero l'iniziativa di cambiare nome al paese, intendendo cancellare il ricordo dell'antica aristocrazia terriera: il nuovo nome prescelto fu «Marxwalde» («boschi di Marx»), in onore del filosofo fondatore del movimento comunista.

Il 1º gennaio 1991, dopo la riunificazione tedesca, Marxwalde riprese la denominazione precedente di «Neuhardenberg».

Nel 2003 venne aggregato al comune di Neuhardenberg il soppresso comune di Quappendorf.

Monumenti e luoghi d'interesse
 Castello (Schloss)  Costruito nel 1763 come dimora padronale di campagna, fu ampliato in stile neoclassico da Karl Friedrich Schinkel a partire dal 1820; il parco (Schlosspark) fu disegnato nel 1821 dal paesaggista Peter Joseph Lenné.
 Chiesa (Dorfkirche)  Eretta dal 1814 al 1817 in stile neoclassico su progetto di Karl Friedrich Schinkel; ad essa è annesso un mausoleo (1823) della famiglia Hardenberg.
 Monumento a Federico II  Risalente al 1792, fu scolpito da Giuseppe Martini seguendo un progetto di Johann Wilhelm Meil.

Geografia antropica
Il comune di Neuhardenberg comprende le seguenti frazioni (Ortsteil):
 Altfriedland (con le località di Gottesgabe, Karlsdorf e Neufriedland)
 Wulkow
 Quappendorf (con la località di Neufeld)

Amministrazione

Gemellaggi
Il comune di Neuhardenberg è gemellato con:

Note

Altri progetti

Collegamenti esterni


For those familiar with Java, the auto-generated Javadoc documentation may be useful as well.
A pedigree file in [PED format][PED] that indicates the name, gender, and affectation status of the samples in the VCF. Samples in the VCF but not in the PED file will be treated as affected females.
A VCF file that has been annotated with dbSNP information (a task that can be completed with the current dbSNP VCF file and the [joinx] utility).
Variant annotation information in Variant Effect Predictor (VEP) format, ideally with canonical, hgnc, Polyphen, SIFT, and Condel options.
Gene expression for the tissue(s) of interest. This should be a one-column text file with HUGO symbols ordered according to their expression level (highest to lowest). This is optional but highly recommended; many gene expression datasets are freely available.
MendelScan calculates four individual scores (segregation, population, annotation, and expression) for each variant. Each score is a value between 0 and 1 reflecting the likelihood that the variant could be disease-causing. The default settings will prioritize novel/rare protein-altering variants in highly expressed genes that segregate in autsomal-dominant fashion. Many of the scoring parameters can be adjusted to suit different kinds of studies. An overall score, taken as the product of the four scores, reflects the relative priority (higher = more likely to cause disease) of variants based on these criteria.
The output file contains each variant along with the overall and individual scores, as well as annotation, population, expression, and segregation data that were used to compute them. A VCF output option is also available; it places an similar but abbreviated information in the INFO field.
A BED file of chromosome centromere coordinates (optional but recommended).
The RHRO method identifies candidate regions consistent with autosomal dominant inheritance based on the idea that a disease-causing haplotype will manifest regions of rare heterozygous variants shared by all affecteds, and an absence of homozygous differences between affected pairs (which would indicate that a pair had no haplotype in common).
There are two output files from this command. One contains all informative variants (rare heterozygotes shared by affecteds, or variant positions with homozygous differences between affected pairs). The second output is a window of RHRO regions that are consistent with autosomal dominant inheritance given the inputs and assumptions described here.
The BEAGLE markers file for the chromosome at hand, which typically includes four columns: physical position (chrom:position), map position (morgans), allele1, and allele2.
The BEAGLE FastIBD output file (*.fibd) for the chromosome in uncompressed format. It should have five columns: sample1, sample2, index1, index2, and score. The index fields correspond to the markers file; MendelScan will convert these to genomic coordinates and print them to the output file.
MendelScan breaks the chromosome into windows of a user-specified resolution (default: 100,000 bp) and, for each window, determines the number of affected pairs that shared an IBD segment in that window. Typically, windows in which >90% of possible affected pairs were IBD suggests a candidate haplotype. All windows are output to a second output file (if specified) or STDOUT.


text:
23-Feb-2011 1:39 PM
BAA blames unions, one-offs and strike action for 2010 losses
Unions, snow, ash and strikes have resulted in BAA reporting a pre-tax loss of GBP317 million for 2010, according to the UK airports operator, which is owned by Spain's Ferrovial.
The largest single contributors to the loss were the cancellation of plans for new runways at Heathrow and Stansted, which cost GBP149 million, and interest charges of nearly GBP400 million on the group's GBP10 billion in debt. Shares in Ferrovial were down 1.7% in trading on Tuesday.
Australian Infrastructure Fund reported a 32% decline in 1HFY2011 revenue, to AUD96.8 million. The airport investment company reported first-half net profit of AUD88.2 million, also down 32%. Shares in the company were flat yesterday, but gained 0.6% in early trading on the ASX.
Elsewhere, Turkish airports operator TAV saw its shares decline 7.1%. The company is partially exposed to the turmoil in North Africa, with airport holdings in Tunisia.
Guangzhou Baiyun International Airport Co announced plans to sell CNY500 million (USD75.9 million) of 1-year bonds on 01-Mar-2010.
Selected ABD daily share price movements (% change): 22-Feb-2011

redpajama_set_name: RedPajamaCommonCrawl


text:
Home News USPS Pays Tribute to America's Last Battleship
USPS Pays Tribute to America's Last Battleship
12 Jun 2019 Wed
The United States Postal Service pays tribute to "America's last battleship" USS Missouri by issuing a nondenominated forever stamp on 11th June.
The issue date marks the 75th anniversary of Missouri's commissioning on June 11, 1944. USS Missouri was the last battleship and the third ship of the United States Navy to be named after the U.S. state of Missouri.
Missouri was ordered in 1940 and commissioned in June 1944. Missouri was the last battleship commissioned by the United States and is best remembered as the site of the surrender of the Empire of Japan which ended World War II.
Missouri received a total of 11 battle stars for service in World War II, Korea, and the Persian Gulf, and was finally decommissioned on 31 March 1992 after serving a total of 17 years of active service.
Its last honour comes from the US Postal Service. To commemorate the 75th anniversary of the ship, a non-denominated stamp was issued on 11th June 2019. The stamp depicts a digital illustration of the ship against the cloudy and sea background.
Image Courtesy: www.linns.com


However difficult it is to finish on your new floor, in time it will be scratched. Scratches on wood floor cannot be avoided, and can cause major damage if left untreated. While the finished floor is resistant to moisture and decay, when a scratch is deep enough to expose unfinished wood, it is easier to allow moisture and dirt to reach the wood. In time, this can cause permanent damage.
Fortunately, there are a few simple steps you can take to treat the finished floor. These steps are often used by beginners to handle the floor, but if you are uncomfortable or unsure of your abilities, don't hesitate to call a professional. There is a difference between scratches on wood floor and carving. Light scratches, deep-surface defects that can usually be repaired or repaired easily. Gouges are injured due to defects in wood floors.
Serious carvings are strikes that have reached deep into wood that have not been completed and cannot be filled with basic finishing. The board with gouge needs to be replaced completely. If you believe your floor has gouges, contact a wood floor professional. The first step in repairing a pre-made floor is to gently remove it completely and immediately around the beginning. Both steel wool and fine sandpaper work well. Be careful not to add new ones scratches on wood floor during this process.


In research, bias can be defined as the process of introducing a systematic error into the sampling and thus encouraging one outcome over the other, (Arnold, 2010). This can be attributed to many reasons, for instance due to experimental error, where the researcher fails to take into account all the research variables. There are many types of biases and all these depend on the research design employed. The following are the possible research biases for both qualitative and quantitative research.
In qualitative research, bias is defined in terms of the validity and reliability of the research findings, (Polit & Beck, 2012). If the findings are not reliable and valid, then they shall be termed as biased. The main disadvantage of bias is that it leads to distortion of truth in addition to producing skewed data.
The moderator is the individual who is responsible for collecting the research data. The moderator can be a source of bias based on his/her facial expressions, mode of dressing, tonal expressions and style of language among other factors. Although this type of bias is hard to eliminate, it can be minimized through maintenance of neutrality in tonal expression, mode of dressing and language.
The way in which questions are asked can influence the answers given by respondents. There is need for the interviewer to determine biased questions and rephrase them. A question forms the main basis in which information is collected and this can lead invalid findings if they are biased. The following are the major ways in which questions can lead to biased research findings.
Another form of bias with regard to asking of questions is asking the respondent a question, which he/her cannot understand. The respondent will be forced give his/her answer based on the perceived understanding and this can give biased information.
Biased answers arise from statements that are generally untrue or partially true. The common occasions where such answers are obtained are when conduction interviews on focus groups. The presence of dominant respondents in focus groups may influence other respondents and this may create skewed answers. Additionally, another source of bias can arise from inconsistent answers especially in questions where one leads to the other question.
Sample refers to subgroup of the target population where research is conducted. If the sample is not screened well, one may interview wrong people. Interviewing respondents who do not form the subgroup constitutes bias. Another form of bias in sample selection is failure to use random sampling in the selection of the sample. Random sampling ensures that the study samples have equal chance of selection.
Sometimes, bias can arise from reporting of the results. This source of bias may arise because of personal beliefs, customs, attitude, culture and errors among many other factors. If the person reporting analyses the research information based on his/her beliefs other than the view perceived by the respondents, the findings shall be compromised and hence biased.
Whereas in qualitative research an effort is made to understand the source of bias, in quantitative research, the researcher tries to eliminate bias.
Design bias encompasses bias that may arise when conducting the experiments, as well as during analysis of the results. Design biases are always common, mostly due to the failure of the researchers to take into account the likely impact of the bias in the research they conduct.
Sampling biases occurs in quantitative research when a researcher compromises with the selection of the study subgroup. For instance, a researcher may decide to omit a certain group in the study sample, or include only a specific group. For example, a study on breast cancer that includes only male participants is said to be biased and its results cannot be extrapolated to cover entire study population that include females. Similarly, when a study is done outside a recreation centre on students in a psychological study is biased since it is not inclusive. The major source of sampling bias occurs in systematic and random sampling.
Random and systematic sampling can be a source of bias if the researcher fails to select a representative sample. For, example, if a research is done on a population of around 10,000 students and the researcher takes a sample size of 40 students, then the research would be deemed biased since it is not representative. Additionally, if on selection process, the researcher picks specific group of students then it would give biased results since the chosen study sample should always possess an equal chance of being studied and this should be randomized.


text:
When Was the Last Time That Liverpool Won the Premier League?
Credit: PAUL ELLIS/AFP/Getty Images
Liverpool Football Club has never won the Premier League. However, it has won its predecessor, the Football League First Division, 18 times, most recently in 1990. Liverpool still competes in, and may win, the Premier League.
The Premier League was founded in 1992 to replace the First Division, as the First Division wanted to break away from the Football League for economic reasons. Liverpool has been runner-up to the Premier League three times: in 2002, in 2009 and most recently in 2014. Manchester United is the most successful club in terms of First Division trophies, having won it 18 times.
How Many Times Has Liverpool Won the Champions League?
How Many Times Has Manchester United Won the Premier League?
How Many Trophies Has Liverpool Won?
How Long Do Eye Floaters Last?


Parker Conrad's start-up, Zenefits, is thought to be one of the fastest-growing companies in recent Silicon Valley history, and his investors and associates describe him as an uncommonly talented software visionary. But lately, Mr. Conrad often finds himself petrified, his days a series of white-knuckled attempts to escape the clutches of sudden, inadvertent failure.
Open self-doubt is an unusual posture for a start-up executive. Tech founders are, as a class, known to be drunk on their own hype. But Mr. Conrad doesn't quite fit the stereotype of the young, hyperconfident brogrammer now reported to be running, and ruining, the tech industry. Though he looks the part — he has a boyish face and favors casual, gamer-guy attire — he is, at 34, relatively old. And while the tech press is consumed by apps like Uber and Airbnb, companies that wear their regulation-smashing, world-changing zeal on their sleeves, Zenefits is unusual in that makes software designed to help small businesses comply with regulations rather than fight them.