Skip to content

Commit cb95006

Browse files
committed
Merge branch 'mc/credential-helper-auth-headers' into next
Extending credential helper protocol. * mc/credential-helper-auth-headers: credential: add WWW-Authenticate header to cred requests http: read HTTP WWW-Authenticate response headers http: replace unsafe size_t multiplication with st_mult test-http-server: add sending of arbitrary headers test-http-server: add simple authentication test-http-server: pass Git requests to http-backend test-http-server: add HTTP request parsing test-http-server: add HTTP error response function test-http-server: add stub HTTP server test helper daemon: rename some esoteric/laboured terminology daemon: libify child process handling functions daemon: libify socket setup and option functions
2 parents aaa3c88 + 026012c commit cb95006

File tree

13 files changed

+1936
-302
lines changed

13 files changed

+1936
-302
lines changed

Documentation/git-credential.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,13 @@ separated by an `=` (equals) sign, followed by a newline.
113113
The key may contain any bytes except `=`, newline, or NUL. The value may
114114
contain any bytes except newline or NUL.
115115

116-
In both cases, all bytes are treated as-is (i.e., there is no quoting,
116+
Attributes with keys that end with C-style array brackets `[]` can have
117+
multiple values. Each instance of a multi-valued attribute forms an
118+
ordered list of values - the order of the repeated attributes defines
119+
the order of the values. An empty multi-valued attribute (`key[]=\n`)
120+
acts to clear any previous entries and reset the list.
121+
122+
In all cases, all bytes are treated as-is (i.e., there is no quoting,
117123
and one cannot transmit a value with newline or NUL in it). The list of
118124
attributes is terminated by a blank line or end-of-file.
119125

@@ -160,6 +166,17 @@ empty string.
160166
Components which are missing from the URL (e.g., there is no
161167
username in the example above) will be left unset.
162168

169+
`wwwauth[]`::
170+
171+
When an HTTP response is received by Git that includes one or more
172+
'WWW-Authenticate' authentication headers, these will be passed by Git
173+
to credential helpers.
174+
+
175+
Each 'WWW-Authenticate' header value is passed as a multi-valued
176+
attribute 'wwwauth[]', where the order of the attributes is the same as
177+
they appear in the HTTP response. This attribute is 'one-way' from Git
178+
to pass additional information to credential helpers.
179+
163180
Unrecognised attributes are silently discarded.
164181

165182
GIT

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ TEST_BUILTINS_OBJS += test-xml-encode.o
867867
# Do not add more tests here unless they have extra dependencies. Add
868868
# them in TEST_BUILTINS_OBJS above.
869869
TEST_PROGRAMS_NEED_X += test-fake-ssh
870+
TEST_PROGRAMS_NEED_X += test-http-server
870871
TEST_PROGRAMS_NEED_X += test-tool
871872

872873
TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
@@ -1005,6 +1006,7 @@ LIB_OBJS += credential.o
10051006
LIB_OBJS += csum-file.o
10061007
LIB_OBJS += ctype.o
10071008
LIB_OBJS += date.o
1009+
LIB_OBJS += daemon-utils.o
10081010
LIB_OBJS += decorate.o
10091011
LIB_OBJS += delta-islands.o
10101012
LIB_OBJS += diagnose.o

contrib/buildsystems/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,9 @@ if(BUILD_TESTING)
961961
add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c)
962962
target_link_libraries(test-fake-ssh common-main)
963963

964+
add_executable(test-http-server ${CMAKE_SOURCE_DIR}/t/helper/test-http-server.c)
965+
target_link_libraries(test-http-server common-main)
966+
964967
#reftable-tests
965968
parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS")
966969
list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
@@ -980,15 +983,19 @@ if(MSVC)
980983
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/helper)
981984
set_target_properties(test-fake-ssh test-tool
982985
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/helper)
986+
987+
set_target_properties(test-http-server
988+
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/helper)
989+
set_target_properties(test-http-server
990+
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/helper)
983991
endif()
984992

985993
#wrapper scripts
986994
set(wrapper_scripts
987995
git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext scalar)
988996

989997
set(wrapper_test_scripts
990-
test-fake-ssh test-tool)
991-
998+
test-http-server test-fake-ssh test-tool)
992999

9931000
foreach(script ${wrapper_scripts})
9941001
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)

credential.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void credential_clear(struct credential *c)
2222
free(c->username);
2323
free(c->password);
2424
string_list_clear(&c->helpers, 0);
25+
strvec_clear(&c->wwwauth_headers);
2526

2627
credential_init(c);
2728
}
@@ -262,13 +263,24 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
262263
fprintf(fp, "%s=%s\n", key, value);
263264
}
264265

266+
static void credential_write_strvec(FILE *fp, const char *key,
267+
const struct strvec *vec)
268+
{
269+
char *full_key = xstrfmt("%s[]", key);
270+
for (size_t i = 0; i < vec->nr; i++) {
271+
credential_write_item(fp, full_key, vec->v[i], 0);
272+
}
273+
free(full_key);
274+
}
275+
265276
void credential_write(const struct credential *c, FILE *fp)
266277
{
267278
credential_write_item(fp, "protocol", c->protocol, 1);
268279
credential_write_item(fp, "host", c->host, 1);
269280
credential_write_item(fp, "path", c->path, 0);
270281
credential_write_item(fp, "username", c->username, 0);
271282
credential_write_item(fp, "password", c->password, 0);
283+
credential_write_strvec(fp, "wwwauth", &c->wwwauth_headers);
272284
}
273285

274286
static int run_credential_helper(struct credential *c,

credential.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define CREDENTIAL_H
33

44
#include "string-list.h"
5+
#include "strvec.h"
56

67
/**
78
* The credentials API provides an abstracted way of gathering username and
@@ -115,6 +116,19 @@ struct credential {
115116
*/
116117
struct string_list helpers;
117118

119+
/**
120+
* A `strvec` of WWW-Authenticate header values. Each string
121+
* is the value of a WWW-Authenticate header in an HTTP response,
122+
* in the order they were received in the response.
123+
*/
124+
struct strvec wwwauth_headers;
125+
126+
/**
127+
* Internal use only. Used to keep track of split header fields
128+
* in order to fold multiple lines into one value.
129+
*/
130+
unsigned header_is_last_match:1;
131+
118132
unsigned approved:1,
119133
configured:1,
120134
quit:1,
@@ -130,6 +144,7 @@ struct credential {
130144

131145
#define CREDENTIAL_INIT { \
132146
.helpers = STRING_LIST_INIT_DUP, \
147+
.wwwauth_headers = STRVEC_INIT, \
133148
}
134149

135150
/* Initialize a credential structure, setting all fields to empty. */

0 commit comments

Comments
 (0)