first simple rxpd access check
[webgit] / src / query.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 #include "query.h"
24 #include "repo.h"
25
26 #include "cwa.h"
27
28 #include <stdint.h>
29 #include <time.h>
30
31 void
32 webgit_query_init (struct webgit_query* q)
33 {
34   q->request = NULL;
35   q->now = time (NULL);
36
37   q->deref_to_tree = 0;
38   q->content_type = cwa_strndup ("text/html", SIZE_MAX);
39
40   q->count_def = 100;
41   q->rxpd = NULL;
42   q->skindir = cwa_strndup (WEBGIT_SKINDIR_DEFAULT, SIZE_MAX);
43   q->webskindir = cwa_strndup (WEBGIT_WEBSKINDIR_DEFAULT, SIZE_MAX);
44
45   q->repo = NULL;
46   q->action = NULL;
47   q->object = NULL;
48   q->head = NULL;
49   q->path = NULL;
50   q->blob = NULL;
51   q->blob_size = 0;
52   q->skin = cwa_strndup (WEBGIT_DEFAULT_SKIN, SIZE_MAX);
53   q->count = -1;
54
55   llist_init (&q->repos);
56 }
57
58 struct webgit_query*
59 webgit_query_destroy (struct webgit_query* q)
60 {
61   cgi_free (q->request);
62
63   free (q->content_type);
64   free (q->rxpd);
65   free (q->skindir);
66   free (q->webskindir);
67
68   free (q->repo);
69   free (q->action);
70   free (q->object);
71   free (q->head);
72   free (q->path);
73   free (q->skin);
74   free (q->blob);
75
76   LLIST_WHILE_HEAD (&q->repos, head)
77     webgit_repoinfo_free ((struct webgit_repo_info*) head);
78
79   return q;
80 }
81
82
83 void
84 webgit_query_add_repo (struct webgit_query* q, const char* path)
85 {
86   struct webgit_repo_info* ri = webgit_repoinfo_new (q, path);
87   if (!ri)
88     return;
89
90   LList p = &q->repos;
91   LLIST_FOREACH (&q->repos, node)
92     {
93       struct webgit_repo_info* n = (struct webgit_repo_info*)node;
94       if (strcmp (n->name, ri->name) > 0)
95         break;
96       p = node;
97     }
98   llist_insert_next (p, &ri->node);
99 }
100
101 int
102 webgit_validate_string (const char *s, size_t v_sz)
103 {
104   for (const char* c = ";$&|<>!`#"; *c; ++c)
105     if (memchr (s, *c, v_sz))
106       return 0;
107
108   if (cwa_memmem (s, v_sz, "..", 2))
109     return 0;
110
111   return 1;
112 }
113
114 static void
115 webgit_repo_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
116 {
117   (void) self;
118   struct webgit_query* q = (struct webgit_query*) u_dat;
119
120   /* TODO validate that v is a probably legal repo name (alnum()) */
121   if (webgit_validate_string (v, v_sz))
122     {
123       free (q->repo);
124       q->repo = cwa_strndup (v, v_sz);
125     }
126 }
127
128
129 static void
130 webgit_action_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
131 {
132   (void) self;
133   struct webgit_query* q = (struct webgit_query*) u_dat;
134
135   /* TODO validate that v is a probably legal action name alpha() */
136   if (webgit_validate_string (v, v_sz))
137     {
138       free (q->action);
139       q->action = cwa_strndup (v, v_sz);
140     }
141 }
142
143
144 static void
145 webgit_object_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
146 {
147   (void) self;
148   struct webgit_query* q = (struct webgit_query*) u_dat;
149
150   if (!q->action)
151     q->action = cwa_strndup ("object", SIZE_MAX);
152
153   /* TODO validate that v is a probably sha1 (<=40 chars, hex) */
154   if (webgit_validate_string (v, v_sz))
155     {
156       free (q->object);
157       q->object = cwa_strndup (v, v_sz);
158     }
159 }
160
161
162 static void
163 webgit_ref_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
164 {
165   (void) self;
166   struct webgit_query* q = (struct webgit_query*) u_dat;
167
168   /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
169   if (webgit_validate_string (v, v_sz))
170     {
171       free (q->head);
172       q->head = cwa_strndup (v, v_sz);
173     }
174 }
175
176
177 static void
178 webgit_path_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
179 {
180   (void) self;
181   struct webgit_query* q = (struct webgit_query*) u_dat;
182
183   /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
184   if (webgit_validate_string (v, v_sz))
185     {
186       free (q->path);
187       q->path = cwa_strndup (v, v_sz);
188     }
189 }
190
191
192 static void
193 webgit_blob_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
194 {
195   (void) self;
196   struct webgit_query* q = (struct webgit_query*) u_dat;
197
198   free (q->blob);
199   q->blob = cwa_malloc (v_sz + 1);
200   q->blob_size = v_sz;
201   memcpy (q->blob, v, v_sz);
202   q->blob[v_sz] = '\0';
203 }
204
205
206 static void
207 webgit_skin_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
208 {
209   (void) self;
210   struct webgit_query* q = (struct webgit_query*) u_dat;
211
212   /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
213   if (webgit_validate_string (v, v_sz))
214     {
215       free (q->skin);
216       q->skin = cwa_strndup (v, v_sz);
217     }
218 }
219
220
221 static void
222 webgit_count_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
223 {
224   (void) self;
225   struct webgit_query* q = (struct webgit_query*) u_dat;
226
227   /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
228   if (webgit_validate_string (v, v_sz))
229     {
230       q->count = atoi (v);
231     }
232 }
233
234
235 void
236 webgit_param_dispatch (const Cgi self,
237                       const char* name,
238                       const char* value,
239                       size_t value_len,
240                       void* user_data)
241 {
242 #define WEBGIT_PARAM(name, _) {#name, webgit_##name##_param},
243   struct param_table{
244     char* name;
245     void (*cb)(const Cgi, const char* v, size_t v_sz, void* u_dat);
246   } cmds[] = {WEBGIT_PARAMS {"", NULL}};
247 #undef WEBGIT_PARAMS
248
249   for (struct param_table* j = cmds; j->cb; ++j)
250     {
251       if (!strcmp (j->name, name))
252         {
253           j->cb (self, value, value_len, user_data);
254           break;
255         }
256     }
257 }
258
259 /*
260 //      Local Variables:
261 //      mode: C
262 //      c-file-style: "gnu"
263 //      indent-tabs-mode: nil
264 //      End:
265 */