1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #include "netops.h"
9 
10 #include <ctype.h>
11 #include "git2/errors.h"
12 
13 #include "posix.h"
14 #include "buffer.h"
15 #include "http_parser.h"
16 #include "runtime.h"
17 
gitno_recv(gitno_buffer * buf)18 int gitno_recv(gitno_buffer *buf)
19 {
20 	return buf->recv(buf);
21 }
22 
gitno_buffer_setup_callback(gitno_buffer * buf,char * data,size_t len,int (* recv)(gitno_buffer * buf),void * cb_data)23 void gitno_buffer_setup_callback(
24 	gitno_buffer *buf,
25 	char *data,
26 	size_t len,
27 	int (*recv)(gitno_buffer *buf), void *cb_data)
28 {
29 	memset(data, 0x0, len);
30 	buf->data = data;
31 	buf->len = len;
32 	buf->offset = 0;
33 	buf->recv = recv;
34 	buf->cb_data = cb_data;
35 }
36 
recv_stream(gitno_buffer * buf)37 static int recv_stream(gitno_buffer *buf)
38 {
39 	git_stream *io = (git_stream *) buf->cb_data;
40 	size_t readlen = buf->len - buf->offset;
41 	ssize_t ret;
42 
43 	readlen = min(readlen, INT_MAX);
44 
45 	ret = git_stream_read(io, buf->data + buf->offset, (int)readlen);
46 	if (ret < 0)
47 		return -1;
48 
49 	buf->offset += ret;
50 	return (int)ret;
51 }
52 
gitno_buffer_setup_fromstream(git_stream * st,gitno_buffer * buf,char * data,size_t len)53 void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len)
54 {
55 	memset(data, 0x0, len);
56 	buf->data = data;
57 	buf->len = len;
58 	buf->offset = 0;
59 	buf->recv = recv_stream;
60 	buf->cb_data = st;
61 }
62 
63 /* Consume up to ptr and move the rest of the buffer to the beginning */
gitno_consume(gitno_buffer * buf,const char * ptr)64 int gitno_consume(gitno_buffer *buf, const char *ptr)
65 {
66 	size_t consumed;
67 
68 	GIT_ASSERT(ptr - buf->data >= 0);
69 	GIT_ASSERT(ptr - buf->data <= (int) buf->len);
70 
71 	consumed = ptr - buf->data;
72 
73 	memmove(buf->data, ptr, buf->offset - consumed);
74 	memset(buf->data + buf->offset, 0x0, buf->len - buf->offset);
75 	buf->offset -= consumed;
76 
77 	return 0;
78 }
79 
80 /* Consume const bytes and move the rest of the buffer to the beginning */
gitno_consume_n(gitno_buffer * buf,size_t cons)81 void gitno_consume_n(gitno_buffer *buf, size_t cons)
82 {
83 	memmove(buf->data, buf->data + cons, buf->len - buf->offset);
84 	memset(buf->data + cons, 0x0, buf->len - buf->offset);
85 	buf->offset -= cons;
86 }
87 
88 /* Match host names according to RFC 2818 rules */
gitno__match_host(const char * pattern,const char * host)89 int gitno__match_host(const char *pattern, const char *host)
90 {
91 	for (;;) {
92 		char c = git__tolower(*pattern++);
93 
94 		if (c == '\0')
95 			return *host ? -1 : 0;
96 
97 		if (c == '*') {
98 			c = *pattern;
99 			/* '*' at the end matches everything left */
100 			if (c == '\0')
101 				return 0;
102 
103 	/*
104 	 * We've found a pattern, so move towards the next matching
105 	 * char. The '.' is handled specially because wildcards aren't
106 	 * allowed to cross subdomains.
107 	 */
108 
109 			while(*host) {
110 				char h = git__tolower(*host);
111 				if (c == h)
112 					return gitno__match_host(pattern, host++);
113 				if (h == '.')
114 					return gitno__match_host(pattern, host);
115 				host++;
116 			}
117 			return -1;
118 		}
119 
120 		if (c != git__tolower(*host++))
121 			return -1;
122 	}
123 
124 	return -1;
125 }
126