mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
Merge pull request #5223 from tiennou/fix/transport-header-split
Circular header splitting
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
v0.28 + 1
|
||||
---------
|
||||
|
||||
### Breaking API changes
|
||||
|
||||
* The "private" implementation details of the `git_cred` structure have been
|
||||
moved to a dedicated `git2/sys/cred.h` header, to clarify that the underlying
|
||||
structures are only provided for custom transport implementers.
|
||||
The breaking change is that the `username` member of the underlying struct
|
||||
is now hidden, and a new `git_cred_get_username` function has been provided.
|
||||
|
||||
### Breaking CMake configuration changes
|
||||
|
||||
* The CMake option to use a system http-parser library, instead of the
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
#include "git2/blame.h"
|
||||
#include "git2/branch.h"
|
||||
#include "git2/buffer.h"
|
||||
#include "git2/cert.h"
|
||||
#include "git2/checkout.h"
|
||||
#include "git2/cherrypick.h"
|
||||
#include "git2/clone.h"
|
||||
#include "git2/commit.h"
|
||||
#include "git2/common.h"
|
||||
#include "git2/config.h"
|
||||
#include "git2/cred.h"
|
||||
#include "git2/deprecated.h"
|
||||
#include "git2/describe.h"
|
||||
#include "git2/diff.h"
|
||||
|
||||
127
include/git2/cert.h
Normal file
127
include/git2/cert.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_git_cert_h__
|
||||
#define INCLUDE_git_cert_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/cert.h
|
||||
* @brief Git certificate objects
|
||||
* @defgroup git_cert Certificate objects
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Type of host certificate structure that is passed to the check callback
|
||||
*/
|
||||
typedef enum git_cert_t {
|
||||
/**
|
||||
* No information about the certificate is available. This may
|
||||
* happen when using curl.
|
||||
*/
|
||||
GIT_CERT_NONE,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to
|
||||
* the DER-encoded data.
|
||||
*/
|
||||
GIT_CERT_X509,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to a
|
||||
* `git_cert_hostkey` structure.
|
||||
*/
|
||||
GIT_CERT_HOSTKEY_LIBSSH2,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to a
|
||||
* `git_strarray` with `name:content` strings containing
|
||||
* information about the certificate. This is used when using
|
||||
* curl.
|
||||
*/
|
||||
GIT_CERT_STRARRAY,
|
||||
} git_cert_t;
|
||||
|
||||
/**
|
||||
* Parent type for `git_cert_hostkey` and `git_cert_x509`.
|
||||
*/
|
||||
struct git_cert {
|
||||
/**
|
||||
* Type of certificate. A `GIT_CERT_` value.
|
||||
*/
|
||||
git_cert_t cert_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the user's custom certificate checks.
|
||||
*
|
||||
* @param cert The host certificate
|
||||
* @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
|
||||
* this certificate is valid
|
||||
* @param host Hostname of the host libgit2 connected to
|
||||
* @param payload Payload provided by the caller
|
||||
* @return 0 to proceed with the connection, < 0 to fail the connection
|
||||
* or > 0 to indicate that the callback refused to act and that
|
||||
* the existing validity determination should be honored
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_transport_certificate_check_cb)(git_cert *cert, int valid, const char *host, void *payload);
|
||||
|
||||
/**
|
||||
* Type of SSH host fingerprint
|
||||
*/
|
||||
typedef enum {
|
||||
/** MD5 is available */
|
||||
GIT_CERT_SSH_MD5 = (1 << 0),
|
||||
/** SHA-1 is available */
|
||||
GIT_CERT_SSH_SHA1 = (1 << 1),
|
||||
} git_cert_ssh_t;
|
||||
|
||||
/**
|
||||
* Hostkey information taken from libssh2
|
||||
*/
|
||||
typedef struct {
|
||||
git_cert parent; /**< The parent cert */
|
||||
|
||||
/**
|
||||
* A hostkey type from libssh2, either
|
||||
* `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
|
||||
*/
|
||||
git_cert_ssh_t type;
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
|
||||
* have the MD5 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_md5[16];
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
|
||||
* have the SHA-1 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_sha1[20];
|
||||
} git_cert_hostkey;
|
||||
|
||||
/**
|
||||
* X.509 certificate information
|
||||
*/
|
||||
typedef struct {
|
||||
git_cert parent; /**< The parent cert */
|
||||
|
||||
/**
|
||||
* Pointer to the X.509 certificate data
|
||||
*/
|
||||
void *data;
|
||||
|
||||
/**
|
||||
* Length of the memory block pointed to by `data`.
|
||||
*/
|
||||
size_t len;
|
||||
} git_cert_x509;
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
308
include/git2/cred.h
Normal file
308
include/git2/cred.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_git_cred_h__
|
||||
#define INCLUDE_git_cred_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/cred.h
|
||||
* @brief Git authentication & credential management
|
||||
* @defgroup git_cred Authentication & credential management
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Supported credential types
|
||||
*
|
||||
* This represents the various types of authentication methods supported by
|
||||
* the library.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* A vanilla user/password request
|
||||
* @see git_cred_userpass_plaintext_new
|
||||
*/
|
||||
GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request
|
||||
* @see git_cred_ssh_key_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_KEY = (1u << 1),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request, with a custom signature
|
||||
* @see git_cred_ssh_custom_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_CUSTOM = (1u << 2),
|
||||
|
||||
/**
|
||||
* An NTLM/Negotiate-based authentication request.
|
||||
* @see git_cred_default
|
||||
*/
|
||||
GIT_CREDTYPE_DEFAULT = (1u << 3),
|
||||
|
||||
/**
|
||||
* An SSH interactive authentication request
|
||||
* @see git_cred_ssh_interactive_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
|
||||
|
||||
/**
|
||||
* Username-only authentication request
|
||||
*
|
||||
* Used as a pre-authentication step if the underlying transport
|
||||
* (eg. SSH, with no username in its URL) does not know which username
|
||||
* to use.
|
||||
*
|
||||
* @see git_cred_username_new
|
||||
*/
|
||||
GIT_CREDTYPE_USERNAME = (1u << 5),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request
|
||||
*
|
||||
* Allows credentials to be read from memory instead of files.
|
||||
* Note that because of differences in crypto backend support, it might
|
||||
* not be functional.
|
||||
*
|
||||
* @see git_cred_ssh_key_memory_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_MEMORY = (1u << 6),
|
||||
} git_credtype_t;
|
||||
|
||||
/**
|
||||
* The base structure for all credential types
|
||||
*/
|
||||
typedef struct git_cred git_cred;
|
||||
|
||||
typedef struct git_cred_userpass_plaintext git_cred_userpass_plaintext;
|
||||
|
||||
/** Username-only credential information */
|
||||
typedef struct git_cred_username git_cred_username;
|
||||
|
||||
/** A key for NTLM/Kerberos "default" credentials */
|
||||
typedef struct git_cred git_cred_default;
|
||||
|
||||
/**
|
||||
* A ssh key from disk
|
||||
*/
|
||||
typedef struct git_cred_ssh_key git_cred_ssh_key;
|
||||
|
||||
/**
|
||||
* Keyboard-interactive based ssh authentication
|
||||
*/
|
||||
typedef struct git_cred_ssh_interactive git_cred_ssh_interactive;
|
||||
|
||||
/**
|
||||
* A key with a custom signature function
|
||||
*/
|
||||
typedef struct git_cred_ssh_custom git_cred_ssh_custom;
|
||||
|
||||
/**
|
||||
* Credential acquisition callback.
|
||||
*
|
||||
* This callback is usually involved any time another system might need
|
||||
* authentication. As such, you are expected to provide a valid git_cred
|
||||
* object back, depending on allowed_types (a git_credtype_t bitmask).
|
||||
*
|
||||
* Note that most authentication details are your responsibility - this
|
||||
* callback will be called until the authentication succeeds, or you report
|
||||
* an error. As such, it's easy to get in a loop if you fail to stop providing
|
||||
* the same incorrect credentials.
|
||||
*
|
||||
* @param cred The newly created credential object.
|
||||
* @param url The resource for which we are demanding a credential.
|
||||
* @param username_from_url The username that was embedded in a "user\@host"
|
||||
* remote url, or NULL if not included.
|
||||
* @param allowed_types A bitmask stating which cred types are OK to return.
|
||||
* @param payload The payload provided when specifying this callback.
|
||||
* @return 0 for success, < 0 to indicate an error, > 0 to indicate
|
||||
* no credential was acquired
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_cred_acquire_cb)(
|
||||
git_cred **cred,
|
||||
const char *url,
|
||||
const char *username_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Free a credential.
|
||||
*
|
||||
* This is only necessary if you own the object; that is, if you are a
|
||||
* transport.
|
||||
*
|
||||
* @param cred the object to free
|
||||
*/
|
||||
GIT_EXTERN(void) git_cred_free(git_cred *cred);
|
||||
|
||||
/**
|
||||
* Check whether a credential object contains username information.
|
||||
*
|
||||
* @param cred object to check
|
||||
* @return 1 if the credential object has non-NULL username, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
|
||||
|
||||
/**
|
||||
* Return the username associated with a credential object.
|
||||
*
|
||||
* @param cred object to check
|
||||
* @return the credential username, or NULL if not applicable
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_cred_get_username(git_cred *cred);
|
||||
|
||||
/**
|
||||
* Create a new plain-text username and password credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username The username of the credential.
|
||||
* @param password The password of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_userpass_plaintext_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *password);
|
||||
|
||||
/**
|
||||
* Create a "default" credential usable for Negotiate mechanisms like NTLM
|
||||
* or Kerberos authentication.
|
||||
*
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_default_new(git_cred **out);
|
||||
|
||||
/**
|
||||
* Create a credential to specify a username.
|
||||
*
|
||||
* This is used with ssh authentication to query for the username if
|
||||
* none is specified in the url.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
|
||||
|
||||
/**
|
||||
* Create a new passphrase-protected ssh key credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @param publickey The path to the public key of the credential.
|
||||
* @param privatekey The path to the private key of the credential.
|
||||
* @param passphrase The passphrase of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
|
||||
/**
|
||||
* Create a new ssh key credential object reading the keys from memory.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate.
|
||||
* @param publickey The public key of the credential.
|
||||
* @param privatekey The private key of the credential.
|
||||
* @param passphrase The passphrase of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_memory_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
|
||||
/*
|
||||
* If the user hasn't included libssh2.h before git2.h, we need to
|
||||
* define a few types for the callback signatures.
|
||||
*/
|
||||
#ifndef LIBSSH2_VERSION
|
||||
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
|
||||
#endif
|
||||
|
||||
typedef void GIT_CALLBACK(git_cred_ssh_interactive_cb)(
|
||||
const char *name,
|
||||
int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
void **abstract);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ssh keyboard-interactive based credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param username Username to use to authenticate.
|
||||
* @param prompt_callback The callback method used for prompts.
|
||||
* @param payload Additional data to pass to the callback.
|
||||
* @return 0 for success or an error code for failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_interactive_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
git_cred_ssh_interactive_cb prompt_callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Create a new ssh key credential object used for querying an ssh-agent.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_from_agent(
|
||||
git_cred **out,
|
||||
const char *username);
|
||||
|
||||
typedef int GIT_CALLBACK(git_cred_sign_cb)(
|
||||
LIBSSH2_SESSION *session,
|
||||
unsigned char **sig, size_t *sig_len,
|
||||
const unsigned char *data, size_t data_len,
|
||||
void **abstract);
|
||||
|
||||
/**
|
||||
* Create an ssh key credential with a custom signing function.
|
||||
*
|
||||
* This lets you use your own function to sign the challenge.
|
||||
*
|
||||
* This function and its credential type is provided for completeness
|
||||
* and wraps `libssh2_userauth_publickey()`, which is undocumented.
|
||||
*
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @param publickey The bytes of the public key.
|
||||
* @param publickey_len The length of the public key in bytes.
|
||||
* @param sign_callback The callback method to sign the data during the challenge.
|
||||
* @param payload Additional data to pass to the callback.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_custom_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
size_t publickey_len,
|
||||
git_cred_sign_cb sign_callback,
|
||||
void *payload);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
@@ -8,7 +8,9 @@
|
||||
#define INCLUDE_git_proxy_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "transport.h"
|
||||
|
||||
#include "cert.h"
|
||||
#include "cred.h"
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
@@ -67,7 +69,7 @@ typedef struct {
|
||||
* connection to proceed. Returns 0 to allow the connection
|
||||
* or a negative value to indicate an error.
|
||||
*/
|
||||
git_transport_certificate_check_cb certificate_check;
|
||||
git_transport_certificate_check_cb certificate_check;
|
||||
|
||||
/**
|
||||
* Payload to be provided to the credentials and certificate
|
||||
|
||||
90
include/git2/sys/cred.h
Normal file
90
include/git2/sys/cred.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_sys_git_cred_h__
|
||||
#define INCLUDE_sys_git_cred_h__
|
||||
|
||||
#include "git2/common.h"
|
||||
#include "git2/cred.h"
|
||||
|
||||
/**
|
||||
* @file git2/sys/cred.h
|
||||
* @brief Git credentials low-level implementation
|
||||
* @defgroup git_cred Git credentials low-level implementation
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* The base structure for all credential types
|
||||
*/
|
||||
struct git_cred {
|
||||
git_credtype_t credtype; /**< A type of credential */
|
||||
|
||||
/** The deallocator for this type of credentials */
|
||||
void GIT_CALLBACK(free)(git_cred *cred);
|
||||
};
|
||||
|
||||
/** A plaintext username and password */
|
||||
struct git_cred_userpass_plaintext {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *password; /**< The password to use */
|
||||
};
|
||||
|
||||
/** Username-only credential information */
|
||||
struct git_cred_username {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char username[1]; /**< The username to authenticate as */
|
||||
};
|
||||
|
||||
/**
|
||||
* A ssh key from disk
|
||||
*/
|
||||
struct git_cred_ssh_key {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *publickey; /**< The path to a public key */
|
||||
char *privatekey; /**< The path to a private key */
|
||||
char *passphrase; /**< Passphrase used to decrypt the private key */
|
||||
};
|
||||
|
||||
/**
|
||||
* Keyboard-interactive based ssh authentication
|
||||
*/
|
||||
struct git_cred_ssh_interactive {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
|
||||
/**
|
||||
* Callback used for authentication.
|
||||
*/
|
||||
git_cred_ssh_interactive_cb prompt_callback;
|
||||
|
||||
void *payload; /**< Payload passed to prompt_callback */
|
||||
};
|
||||
|
||||
/**
|
||||
* A key with a custom signature function
|
||||
*/
|
||||
struct git_cred_ssh_custom {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *publickey; /**< The public key data */
|
||||
size_t publickey_len; /**< Length of the public key */
|
||||
|
||||
/**
|
||||
* Callback used to sign the data.
|
||||
*/
|
||||
git_cred_sign_cb sign_callback;
|
||||
|
||||
void *payload; /**< Payload passed to prompt_callback */
|
||||
};
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "indexer.h"
|
||||
#include "net.h"
|
||||
#include "types.h"
|
||||
#include "cert.h"
|
||||
#include "cred.h"
|
||||
|
||||
/**
|
||||
* @file git2/transport.h
|
||||
@@ -20,366 +22,21 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Callback for messages recieved by the transport.
|
||||
*
|
||||
* Return a negative value to cancel the network operation.
|
||||
*
|
||||
* @param str The message from the transport
|
||||
* @param len The length of the message
|
||||
* @param payload Payload provided by the caller
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_transport_message_cb)(const char *str, int len, void *payload);
|
||||
|
||||
/** Signature of a function which creates a transport */
|
||||
typedef int GIT_CALLBACK(git_transport_cb)(git_transport **out, git_remote *owner, void *param);
|
||||
|
||||
/**
|
||||
* Type of SSH host fingerprint
|
||||
*/
|
||||
typedef enum {
|
||||
/** MD5 is available */
|
||||
GIT_CERT_SSH_MD5 = (1 << 0),
|
||||
/** SHA-1 is available */
|
||||
GIT_CERT_SSH_SHA1 = (1 << 1),
|
||||
} git_cert_ssh_t;
|
||||
|
||||
/**
|
||||
* Hostkey information taken from libssh2
|
||||
*/
|
||||
typedef struct {
|
||||
git_cert parent; /**< The parent cert */
|
||||
|
||||
/**
|
||||
* A hostkey type from libssh2, either
|
||||
* `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
|
||||
*/
|
||||
git_cert_ssh_t type;
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
|
||||
* have the MD5 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_md5[16];
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
|
||||
* have the SHA-1 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_sha1[20];
|
||||
} git_cert_hostkey;
|
||||
|
||||
/**
|
||||
* X.509 certificate information
|
||||
*/
|
||||
typedef struct {
|
||||
git_cert parent; /**< The parent cert */
|
||||
|
||||
/**
|
||||
* Pointer to the X.509 certificate data
|
||||
*/
|
||||
void *data;
|
||||
|
||||
/**
|
||||
* Length of the memory block pointed to by `data`.
|
||||
*/
|
||||
size_t len;
|
||||
} git_cert_x509;
|
||||
|
||||
/*
|
||||
*** Begin interface for credentials acquisition ***
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supported credential types
|
||||
*
|
||||
* This represents the various types of authentication methods supported by
|
||||
* the library.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* A vanilla user/password request
|
||||
* @see git_cred_userpass_plaintext_new
|
||||
*/
|
||||
GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request
|
||||
* @see git_cred_ssh_key_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_KEY = (1u << 1),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request, with a custom signature
|
||||
* @see git_cred_ssh_custom_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_CUSTOM = (1u << 2),
|
||||
|
||||
/**
|
||||
* An NTLM/Negotiate-based authentication request.
|
||||
* @see git_cred_default
|
||||
*/
|
||||
GIT_CREDTYPE_DEFAULT = (1u << 3),
|
||||
|
||||
/**
|
||||
* An SSH interactive authentication request
|
||||
* @see git_cred_ssh_interactive_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
|
||||
|
||||
/**
|
||||
* Username-only authentication request
|
||||
*
|
||||
* Used as a pre-authentication step if the underlying transport
|
||||
* (eg. SSH, with no username in its URL) does not know which username
|
||||
* to use.
|
||||
*
|
||||
* @see git_cred_username_new
|
||||
*/
|
||||
GIT_CREDTYPE_USERNAME = (1u << 5),
|
||||
|
||||
/**
|
||||
* An SSH key-based authentication request
|
||||
*
|
||||
* Allows credentials to be read from memory instead of files.
|
||||
* Note that because of differences in crypto backend support, it might
|
||||
* not be functional.
|
||||
*
|
||||
* @see git_cred_ssh_key_memory_new
|
||||
*/
|
||||
GIT_CREDTYPE_SSH_MEMORY = (1u << 6),
|
||||
} git_credtype_t;
|
||||
|
||||
typedef struct git_cred git_cred;
|
||||
|
||||
/**
|
||||
* The base structure for all credential types
|
||||
*/
|
||||
struct git_cred {
|
||||
git_credtype_t credtype; /**< A type of credential */
|
||||
|
||||
/** The deallocator for this type of credentials */
|
||||
void GIT_CALLBACK(free)(git_cred *cred);
|
||||
};
|
||||
|
||||
/** A plaintext username and password */
|
||||
typedef struct {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *password; /**< The password to use */
|
||||
} git_cred_userpass_plaintext;
|
||||
|
||||
|
||||
/*
|
||||
* If the user hasn't included libssh2.h before git2.h, we need to
|
||||
* define a few types for the callback signatures.
|
||||
*/
|
||||
#ifndef LIBSSH2_VERSION
|
||||
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
|
||||
#endif
|
||||
|
||||
typedef int GIT_CALLBACK(git_cred_sign_cb)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
|
||||
typedef void GIT_CALLBACK(git_cred_ssh_interactive_cb)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract);
|
||||
|
||||
/**
|
||||
* A ssh key from disk
|
||||
*/
|
||||
typedef struct git_cred_ssh_key {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *publickey; /**< The path to a public key */
|
||||
char *privatekey; /**< The path to a private key */
|
||||
char *passphrase; /**< Passphrase used to decrypt the private key */
|
||||
} git_cred_ssh_key;
|
||||
|
||||
/**
|
||||
* Keyboard-interactive based ssh authentication
|
||||
*/
|
||||
typedef struct git_cred_ssh_interactive {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
|
||||
/**
|
||||
* Callback used for authentication.
|
||||
*/
|
||||
git_cred_ssh_interactive_cb prompt_callback;
|
||||
|
||||
void *payload; /**< Payload passed to prompt_callback */
|
||||
} git_cred_ssh_interactive;
|
||||
|
||||
/**
|
||||
* A key with a custom signature function
|
||||
*/
|
||||
typedef struct git_cred_ssh_custom {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char *username; /**< The username to authenticate as */
|
||||
char *publickey; /**< The public key data */
|
||||
size_t publickey_len; /**< Length of the public key */
|
||||
|
||||
/**
|
||||
* Callback used to sign the data.
|
||||
*/
|
||||
git_cred_sign_cb sign_callback;
|
||||
|
||||
void *payload; /**< Payload passed to prompt_callback */
|
||||
} git_cred_ssh_custom;
|
||||
|
||||
/** A key for NTLM/Kerberos "default" credentials */
|
||||
typedef struct git_cred git_cred_default;
|
||||
|
||||
/** Username-only credential information */
|
||||
typedef struct git_cred_username {
|
||||
git_cred parent; /**< The parent cred */
|
||||
char username[1]; /**< The username to authenticate as */
|
||||
} git_cred_username;
|
||||
|
||||
/**
|
||||
* Check whether a credential object contains username information.
|
||||
*
|
||||
* @param cred object to check
|
||||
* @return 1 if the credential object has non-NULL username, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
|
||||
|
||||
/**
|
||||
* Create a new plain-text username and password credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username The username of the credential.
|
||||
* @param password The password of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_userpass_plaintext_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *password);
|
||||
|
||||
/**
|
||||
* Create a new passphrase-protected ssh key credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @param publickey The path to the public key of the credential.
|
||||
* @param privatekey The path to the private key of the credential.
|
||||
* @param passphrase The passphrase of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
|
||||
/**
|
||||
* Create a new ssh keyboard-interactive based credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param username Username to use to authenticate.
|
||||
* @param prompt_callback The callback method used for prompts.
|
||||
* @param payload Additional data to pass to the callback.
|
||||
* @return 0 for success or an error code for failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_interactive_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
git_cred_ssh_interactive_cb prompt_callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Create a new ssh key credential object used for querying an ssh-agent.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_from_agent(
|
||||
git_cred **out,
|
||||
const char *username);
|
||||
|
||||
/**
|
||||
* Create an ssh key credential with a custom signing function.
|
||||
*
|
||||
* This lets you use your own function to sign the challenge.
|
||||
*
|
||||
* This function and its credential type is provided for completeness
|
||||
* and wraps `libssh2_userauth_publickey()`, which is undocumented.
|
||||
*
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate
|
||||
* @param publickey The bytes of the public key.
|
||||
* @param publickey_len The length of the public key in bytes.
|
||||
* @param sign_callback The callback method to sign the data during the challenge.
|
||||
* @param payload Additional data to pass to the callback.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_custom_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
size_t publickey_len,
|
||||
git_cred_sign_cb sign_callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Create a "default" credential usable for Negotiate mechanisms like NTLM
|
||||
* or Kerberos authentication.
|
||||
*
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_default_new(git_cred **out);
|
||||
|
||||
/**
|
||||
* Create a credential to specify a username.
|
||||
*
|
||||
* This is used with ssh authentication to query for the username if
|
||||
* none is specified in the url.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
|
||||
|
||||
/**
|
||||
* Create a new ssh key credential object reading the keys from memory.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username username to use to authenticate.
|
||||
* @param publickey The public key of the credential.
|
||||
* @param privatekey The private key of the credential.
|
||||
* @param passphrase The passphrase of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_ssh_key_memory_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *publickey,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
|
||||
|
||||
/**
|
||||
* Free a credential.
|
||||
*
|
||||
* This is only necessary if you own the object; that is, if you are a
|
||||
* transport.
|
||||
*
|
||||
* @param cred the object to free
|
||||
*/
|
||||
GIT_EXTERN(void) git_cred_free(git_cred *cred);
|
||||
|
||||
/**
|
||||
* Signature of a function which acquires a credential object.
|
||||
*
|
||||
* @param cred The newly created credential object.
|
||||
* @param url The resource for which we are demanding a credential.
|
||||
* @param username_from_url The username that was embedded in a "user\@host"
|
||||
* remote url, or NULL if not included.
|
||||
* @param allowed_types A bitmask stating which cred types are OK to return.
|
||||
* @param payload The payload provided when specifying this callback.
|
||||
* @return 0 for success, < 0 to indicate an error, > 0 to indicate
|
||||
* no credential was acquired
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_cred_acquire_cb)(
|
||||
git_cred **cred,
|
||||
const char *url,
|
||||
const char *username_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
||||
@@ -244,68 +244,10 @@ typedef struct git_push git_push;
|
||||
typedef struct git_remote_head git_remote_head;
|
||||
typedef struct git_remote_callbacks git_remote_callbacks;
|
||||
|
||||
/**
|
||||
* Type for messages delivered by the transport. Return a negative value
|
||||
* to cancel the network operation.
|
||||
*
|
||||
* @param str The message from the transport
|
||||
* @param len The length of the message
|
||||
* @param payload Payload provided by the caller
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_transport_message_cb)(const char *str, int len, void *payload);
|
||||
|
||||
|
||||
/**
|
||||
* Type of host certificate structure that is passed to the check callback
|
||||
*/
|
||||
typedef enum git_cert_t {
|
||||
/**
|
||||
* No information about the certificate is available. This may
|
||||
* happen when using curl.
|
||||
*/
|
||||
GIT_CERT_NONE,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to
|
||||
* the DER-encoded data.
|
||||
*/
|
||||
GIT_CERT_X509,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to a
|
||||
* `git_cert_hostkey` structure.
|
||||
*/
|
||||
GIT_CERT_HOSTKEY_LIBSSH2,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to a
|
||||
* `git_strarray` with `name:content` strings containing
|
||||
* information about the certificate. This is used when using
|
||||
* curl.
|
||||
*/
|
||||
GIT_CERT_STRARRAY,
|
||||
} git_cert_t;
|
||||
|
||||
/**
|
||||
* Parent type for `git_cert_hostkey` and `git_cert_x509`.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Type of certificate. A `GIT_CERT_` value.
|
||||
*/
|
||||
git_cert_t cert_type;
|
||||
} git_cert;
|
||||
|
||||
/**
|
||||
* Callback for the user's custom certificate checks.
|
||||
*
|
||||
* @param cert The host certificate
|
||||
* @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
|
||||
* this certificate is valid
|
||||
* @param host Hostname of the host libgit2 connected to
|
||||
* @param payload Payload provided by the caller
|
||||
* @return 0 to proceed with the connection, < 0 to fail the connection
|
||||
* or > 0 to indicate that the callback refused to act and that
|
||||
* the existing validity determination should be honored
|
||||
*/
|
||||
typedef int GIT_CALLBACK(git_transport_certificate_check_cb)(git_cert *cert, int valid, const char *host, void *payload);
|
||||
typedef struct git_cert git_cert;
|
||||
|
||||
/**
|
||||
* Opaque structure representing a submodule.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "git2.h"
|
||||
#include "buffer.h"
|
||||
#include "git2/sys/cred.h"
|
||||
|
||||
static int basic_next_token(
|
||||
git_buf *out,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "buffer.h"
|
||||
#include "auth.h"
|
||||
#include "auth_ntlm.h"
|
||||
#include "git2/sys/cred.h"
|
||||
|
||||
#ifdef GIT_NTLM
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "cred.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "git2.h"
|
||||
#include "smart.h"
|
||||
#include "git2/cred.h"
|
||||
#include "git2/sys/cred.h"
|
||||
#include "git2/cred_helpers.h"
|
||||
|
||||
static int git_cred_ssh_key_type_new(
|
||||
@@ -27,7 +27,7 @@ int git_cred_has_username(git_cred *cred)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *git_cred__username(git_cred *cred)
|
||||
const char *git_cred_get_username(git_cred *cred)
|
||||
{
|
||||
switch (cred->credtype) {
|
||||
case GIT_CREDTYPE_USERNAME:
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_transports_cred_h__
|
||||
#define INCLUDE_transports_cred_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "git2/transport.h"
|
||||
|
||||
const char *git_cred__username(git_cred *cred);
|
||||
|
||||
#endif
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "netops.h"
|
||||
#include "global.h"
|
||||
#include "remote.h"
|
||||
#include "git2/sys/cred.h"
|
||||
#include "smart.h"
|
||||
#include "auth.h"
|
||||
#include "http.h"
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
#include "net.h"
|
||||
#include "netops.h"
|
||||
#include "smart.h"
|
||||
#include "cred.h"
|
||||
#include "streams/socket.h"
|
||||
|
||||
#include "git2/cred.h"
|
||||
#include "git2/sys/cred.h"
|
||||
|
||||
#ifdef GIT_SSH
|
||||
|
||||
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
|
||||
@@ -629,7 +631,7 @@ post_extract:
|
||||
if ((error = request_creds(&cred, t, urldata.username, auth_methods)) < 0)
|
||||
goto done;
|
||||
|
||||
if (strcmp(urldata.username, git_cred__username(cred))) {
|
||||
if (strcmp(urldata.username, git_cred_get_username(cred))) {
|
||||
git_error_set(GIT_ERROR_SSH, "username does not match previous request");
|
||||
error = -1;
|
||||
goto done;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "repository.h"
|
||||
#include "global.h"
|
||||
#include "http.h"
|
||||
#include "git2/sys/cred.h"
|
||||
|
||||
#include <wincrypt.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
@@ -23,28 +23,24 @@ void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
|
||||
|
||||
cl_git_fail(git_cred_userpass(&cred, NULL, NULL, 0, &payload));
|
||||
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
|
||||
cred->free(cred);
|
||||
git_cred_free(cred);
|
||||
}
|
||||
|
||||
void test_network_cred__stock_userpass_properly_handles_username_in_url(void)
|
||||
{
|
||||
git_cred *cred;
|
||||
git_cred_userpass_plaintext *plain;
|
||||
git_cred_userpass_payload payload = {"alice", "password"};
|
||||
|
||||
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
|
||||
plain = (git_cred_userpass_plaintext*)cred;
|
||||
cl_assert_equal_s(plain->username, "alice");
|
||||
cred->free(cred);
|
||||
cl_assert_equal_s("alice", git_cred_get_username(cred));
|
||||
git_cred_free(cred);
|
||||
|
||||
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
|
||||
plain = (git_cred_userpass_plaintext*)cred;
|
||||
cl_assert_equal_s(plain->username, "alice");
|
||||
cred->free(cred);
|
||||
cl_assert_equal_s("alice", git_cred_get_username(cred));
|
||||
git_cred_free(cred);
|
||||
|
||||
payload.username = NULL;
|
||||
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
|
||||
plain = (git_cred_userpass_plaintext*)cred;
|
||||
cl_assert_equal_s(plain->username, "bob");
|
||||
cred->free(cred);
|
||||
cl_assert_equal_s("bob", git_cred_get_username(cred));
|
||||
git_cred_free(cred);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user