mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 18:03:14 +08:00
c lib: Avoid the infinite loop of trying invalid credentials
LibGit2 has been designed in a strange way. It doesn't give us an easy way of knowing if and why the credentials has failed, it jusst keep calling the credentials failed method. We are now working around this.
This commit is contained in:
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
@ -16,6 +15,7 @@ gj_error *gj_error_info(int err)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gj_error *error = (gj_error *)malloc(sizeof(gj_error));
|
gj_error *error = (gj_error *)malloc(sizeof(gj_error));
|
||||||
|
error->message_allocated = false;
|
||||||
if (err == GJ_ERR_EMPTY_COMMIT)
|
if (err == GJ_ERR_EMPTY_COMMIT)
|
||||||
{
|
{
|
||||||
error->code = 954;
|
error->code = 954;
|
||||||
@ -24,15 +24,25 @@ gj_error *gj_error_info(int err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const git_error *e = git_error_last();
|
const git_error *e = git_error_last();
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
error->code = e->klass;
|
error->code = e->klass;
|
||||||
error->message = (char *)malloc(strlen(e->message));
|
error->message = (char *)malloc(strlen(e->message));
|
||||||
strcpy(error->message, e->message);
|
strcpy(error->message, e->message);
|
||||||
|
error->message_allocated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error->code = 1000;
|
||||||
|
error->message = "Unknown Message";
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gj_error_free(const gj_error *err)
|
void gj_error_free(const gj_error *err)
|
||||||
{
|
{
|
||||||
|
if (err->message_allocated)
|
||||||
free(err->message);
|
free(err->message);
|
||||||
free((void *)err);
|
free((void *)err);
|
||||||
}
|
}
|
||||||
@ -80,7 +90,7 @@ int rm_match_cb(const char *path, const char *spec, void *payload)
|
|||||||
char *git_base_path = (char *)payload;
|
char *git_base_path = (char *)payload;
|
||||||
if (!git_base_path)
|
if (!git_base_path)
|
||||||
{
|
{
|
||||||
printf("git_base_path not in payload. Why?");
|
printf("git_base_path not in payload. Why?\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,9 +294,26 @@ void gj_set_ssh_keys_paths(char *public_key, char *private_key, char *passcode)
|
|||||||
g_passcode = passcode;
|
g_passcode = passcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
bool first_time;
|
||||||
|
} gj_credentials_payload;
|
||||||
|
|
||||||
int credentials_cb(git_cred **out, const char *url, const char *username_from_url,
|
int credentials_cb(git_cred **out, const char *url, const char *username_from_url,
|
||||||
unsigned int allowed_types, void *payload)
|
unsigned int allowed_types, void *payload)
|
||||||
{
|
{
|
||||||
|
if (!payload)
|
||||||
|
{
|
||||||
|
printf("credentials_cb has no payload\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
gj_credentials_payload *gj_payload = (gj_credentials_payload *)payload;
|
||||||
|
if (!gj_payload->first_time)
|
||||||
|
{
|
||||||
|
printf("GitJournal: Credentials have been tried and they failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
printf("UsernameProvided: %s\n", username_from_url);
|
printf("UsernameProvided: %s\n", username_from_url);
|
||||||
printf("Allowed Types: %d\n", allowed_types);
|
printf("Allowed Types: %d\n", allowed_types);
|
||||||
printf("Payload: %p\n", payload);
|
printf("Payload: %p\n", payload);
|
||||||
@ -297,15 +324,10 @@ int credentials_cb(git_cred **out, const char *url, const char *username_from_ur
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = git_cred_ssh_key_new(out, username_from_url,
|
printf("gj_paylaod: %p\n", gj_payload);
|
||||||
|
gj_payload->first_time = false;
|
||||||
|
return git_cred_ssh_key_new(out, username_from_url,
|
||||||
g_public_key_path, g_private_key_path, g_passcode);
|
g_public_key_path, g_private_key_path, g_passcode);
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
printf("Credentials CB Error");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int certificate_check_cb(git_cert *cert, int valid, const char *host, void *payload)
|
int certificate_check_cb(git_cert *cert, int valid, const char *host, void *payload)
|
||||||
@ -332,9 +354,12 @@ int gj_git_clone(char *clone_url, char *git_base_path)
|
|||||||
git_repository *repo = NULL;
|
git_repository *repo = NULL;
|
||||||
git_clone_options options = GIT_CLONE_OPTIONS_INIT;
|
git_clone_options options = GIT_CLONE_OPTIONS_INIT;
|
||||||
options.fetch_opts.callbacks.transfer_progress = fetch_progress;
|
options.fetch_opts.callbacks.transfer_progress = fetch_progress;
|
||||||
options.fetch_opts.callbacks.credentials = credentials_cb;
|
|
||||||
options.fetch_opts.callbacks.certificate_check = certificate_check_cb;
|
options.fetch_opts.callbacks.certificate_check = certificate_check_cb;
|
||||||
|
|
||||||
|
gj_credentials_payload gj_payload = {true};
|
||||||
|
options.fetch_opts.callbacks.payload = (void *)&gj_payload;
|
||||||
|
options.fetch_opts.callbacks.credentials = credentials_cb;
|
||||||
|
|
||||||
err = git_clone(&repo, clone_url, git_base_path, &options);
|
err = git_clone(&repo, clone_url, git_base_path, &options);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -365,6 +390,9 @@ int gj_git_push(char *git_base_path)
|
|||||||
const git_strarray refs = {&name, 1};
|
const git_strarray refs = {&name, 1};
|
||||||
|
|
||||||
git_push_options options = GIT_PUSH_OPTIONS_INIT;
|
git_push_options options = GIT_PUSH_OPTIONS_INIT;
|
||||||
|
|
||||||
|
gj_credentials_payload gj_payload = {true};
|
||||||
|
options.callbacks.payload = (void *)&gj_payload;
|
||||||
options.callbacks.credentials = credentials_cb;
|
options.callbacks.credentials = credentials_cb;
|
||||||
|
|
||||||
err = git_remote_push(remote, &refs, &options);
|
err = git_remote_push(remote, &refs, &options);
|
||||||
@ -397,6 +425,9 @@ int gj_git_pull(char *git_base_path, char *author_name, char *author_email)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
|
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
|
||||||
|
|
||||||
|
gj_credentials_payload gj_payload = {true};
|
||||||
|
options.callbacks.payload = (void *)&gj_payload;
|
||||||
options.callbacks.credentials = credentials_cb;
|
options.callbacks.credentials = credentials_cb;
|
||||||
|
|
||||||
err = git_remote_fetch(remote, NULL, &options, NULL);
|
err = git_remote_fetch(remote, NULL, &options, NULL);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef _GITJOURNAL_H_
|
#ifndef _GITJOURNAL_H_
|
||||||
#define _GITJOURNAL_H_
|
#define _GITJOURNAL_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
int gj_init();
|
int gj_init();
|
||||||
int gj_shutdown();
|
int gj_shutdown();
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ void gj_set_ssh_keys_paths(char *public_key, char *private_key, char *passcode);
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *message;
|
char *message;
|
||||||
|
bool message_allocated;
|
||||||
int code;
|
int code;
|
||||||
} gj_error;
|
} gj_error;
|
||||||
|
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
set -euv
|
set -euv
|
||||||
|
|
||||||
clang test.c gitjournal.c -lgit2
|
clang -g test.c gitjournal.c -lgit2
|
||||||
|
Reference in New Issue
Block a user