]>
Commit | Line | Data |
---|---|---|
76652ff6 AM |
1 | --- cvs-1.12.13.orig/debian/patches/68_DSA_external_passwd_file |
2 | +++ cvs-1.12.13/debian/patches/68_DSA_external_passwd_file | |
3 | @@ -0,0 +1,388 @@ | |
4 | +# Add support for overriding lookups in CVSROOT/passwd | |
5 | +# Specify --password-file <file> on the pserver command line to use it | |
6 | +# Initial patch from the Debian DSA team, adapted by Steve McIntyre. | |
7 | +# See README.Debian for more details. | |
8 | +diff -ruN cvs-1.12.13-old/src/cvs.h cvs-1.12.13/src/cvs.h | |
9 | +--- cvs-1.12.13-old/src/cvs.h 2005-10-02 16:17:20.000000000 +0100 | |
10 | ++++ cvs-1.12.13/src/cvs.h 2006-08-19 01:20:33.000000000 +0100 | |
11 | +@@ -371,6 +371,7 @@ | |
12 | + extern int use_editor; | |
13 | + extern int cvswrite; | |
14 | + extern mode_t cvsumask; | |
15 | ++extern char *PasswordFileName; | |
16 | + | |
17 | + /* Temp dir abstraction. */ | |
18 | + /* From main.c. */ | |
19 | +diff -ruN cvs-1.12.13-old/src/main.c cvs-1.12.13/src/main.c | |
20 | +--- cvs-1.12.13-old/src/main.c 2006-08-17 00:25:16.000000000 +0100 | |
21 | ++++ cvs-1.12.13/src/main.c 2006-08-19 01:20:03.000000000 +0100 | |
22 | +@@ -43,8 +43,7 @@ | |
23 | + int noexec = 0; | |
24 | + int readonlyfs = 0; | |
25 | + int logoff = 0; | |
26 | +- | |
27 | +- | |
28 | ++char *PasswordFileName = NULL; | |
29 | + | |
30 | + /*** | |
31 | + *** | |
32 | +@@ -519,6 +518,7 @@ | |
33 | + {"help-commands", 0, NULL, 1}, | |
34 | + {"help-synonyms", 0, NULL, 2}, | |
35 | + {"help-options", 0, NULL, 4}, | |
36 | ++ {"password-file", required_argument, NULL, 5}, | |
37 | + #ifdef SERVER_SUPPORT | |
38 | + {"allow-root", required_argument, NULL, 3}, | |
39 | + #endif /* SERVER_SUPPORT */ | |
40 | +@@ -646,6 +646,10 @@ | |
41 | + root_allow_add (optarg, gConfigPath); | |
42 | + break; | |
43 | + #endif /* SERVER_SUPPORT */ | |
44 | ++ case 5: | |
45 | ++ /* --password-file */ | |
46 | ++ PasswordFileName = xstrdup(optarg); | |
47 | ++ break; | |
48 | + case 'Q': | |
49 | + really_quiet = 1; | |
50 | + /* FALL THROUGH */ | |
51 | +diff -ruN cvs-1.12.13-old/src/Makefile.in cvs-1.12.13/src/Makefile.in | |
52 | +--- cvs-1.12.13-old/src/Makefile.in 2005-10-03 14:37:18.000000000 +0100 | |
53 | ++++ cvs-1.12.13/src/Makefile.in 2006-08-17 00:28:35.000000000 +0100 | |
54 | +@@ -146,7 +146,7 @@ | |
55 | + ls.$(OBJEXT) main.$(OBJEXT) mkmodules.$(OBJEXT) \ | |
56 | + modules.$(OBJEXT) ms-buffer.$(OBJEXT) myndbm.$(OBJEXT) \ | |
57 | + no_diff.$(OBJEXT) parseinfo.$(OBJEXT) patch.$(OBJEXT) \ | |
58 | +- rcs.$(OBJEXT) rcscmds.$(OBJEXT) recurse.$(OBJEXT) \ | |
59 | ++ rcs.$(OBJEXT) rcscmds.$(OBJEXT) readpw.$(OBJEXT) recurse.$(OBJEXT) \ | |
60 | + release.$(OBJEXT) remove.$(OBJEXT) repos.$(OBJEXT) \ | |
61 | + root.$(OBJEXT) rsh-client.$(OBJEXT) run.$(OBJEXT) \ | |
62 | + scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \ | |
63 | +@@ -349,6 +349,7 @@ | |
64 | + patch.c \ | |
65 | + rcs.c \ | |
66 | + rcscmds.c \ | |
67 | ++ readpw.c \ | |
68 | + recurse.c \ | |
69 | + release.c \ | |
70 | + remove.c \ | |
71 | +@@ -543,6 +544,7 @@ | |
72 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patch.Po@am__quote@ | |
73 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcs.Po@am__quote@ | |
74 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcscmds.Po@am__quote@ | |
75 | ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readpw.Po@am__quote@ | |
76 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recurse.Po@am__quote@ | |
77 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/release.Po@am__quote@ | |
78 | + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remove.Po@am__quote@ | |
79 | +diff -ruN cvs-1.12.13-old/src/parseinfo.h cvs-1.12.13/src/parseinfo.h | |
80 | +--- cvs-1.12.13-old/src/parseinfo.h 2006-08-17 00:25:16.000000000 +0100 | |
81 | ++++ cvs-1.12.13/src/parseinfo.h 2006-08-17 00:58:25.000000000 +0100 | |
82 | +@@ -21,6 +21,7 @@ | |
83 | + char *HistoryLogPath; | |
84 | + char *HistorySearchPath; | |
85 | + char *TmpDir; | |
86 | ++ char *PasswordFileName; | |
87 | + | |
88 | + /* Should the logmsg be re-read during the do_verify phase? | |
89 | + * RereadLogAfterVerify=no|stat|yes | |
90 | +diff -ruN cvs-1.12.13-old/src/readpw.c cvs-1.12.13/src/readpw.c | |
91 | +--- cvs-1.12.13-old/src/readpw.c 1970-01-01 01:00:00.000000000 +0100 | |
92 | ++++ cvs-1.12.13/src/readpw.c 2006-08-19 01:45:26.000000000 +0100 | |
93 | +@@ -0,0 +1,158 @@ | |
94 | ++/* | |
95 | ++ readpw.c - read the CVS password from an external file | |
96 | ++ Copyright (c) 2006 Martin Schulze <joey@infodrom.org> | |
97 | ++ | |
98 | ++ This program is free software; you can redistribute it and/or modify | |
99 | ++ it under the terms of the GNU General Public License as published by | |
100 | ++ the Free Software Foundation; either version 2 of the License, or | |
101 | ++ (at your option) any later version. | |
102 | ++ | |
103 | ++ This program is distributed in the hope that it will be useful, | |
104 | ++ but WITHOUT ANY WARRANTY; without even the implied warranty of | |
105 | ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
106 | ++ GNU General Public License for more details. | |
107 | ++ | |
108 | ++ You should have received a copy of the GNU General Public License | |
109 | ++ along with this program; if not, write to the Free Software | |
110 | ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
111 | ++*/ | |
112 | ++ | |
113 | ++#include <string.h> | |
114 | ++#include <stdio.h> | |
115 | ++#include <errno.h> | |
116 | ++#include <syslog.h> | |
117 | ++ | |
118 | ++#define PWFILE "/tmp/work/cvs/cvs.passwd" | |
119 | ++ | |
120 | ++/* | |
121 | ++ * Source: control_nextline() in dtaus.c from dtaus | |
122 | ++ */ | |
123 | ++size_t readline (FILE *f, char **buf, unsigned int len) | |
124 | ++{ | |
125 | ++ char line[100]; | |
126 | ++ char tmp[100]; | |
127 | ++ char *cp; | |
128 | ++ int i; | |
129 | ++ | |
130 | ++ memset (line, 0, sizeof(line)); | |
131 | ++ memset (*buf, 0, len); | |
132 | ++ | |
133 | ++ cp = line; | |
134 | ++ | |
135 | ++ while (!strlen(line) && (cp = fgets(line, 100, f))) { | |
136 | ++ if (strlen(line)) { | |
137 | ++ if (line[0] != '#') { | |
138 | ++ if (line[strlen(line)-1] != '\n') { | |
139 | ++ strcpy(tmp, line); | |
140 | ++ while (tmp[strlen(tmp)-1] != '\n' && (cp = fgets(tmp, 100, f))); | |
141 | ++ } else | |
142 | ++ line[strlen(line)-1] = '\0'; | |
143 | ++ if (line[strlen(line)-1] == '\r') | |
144 | ++ line[strlen(line)-1] = '\0'; | |
145 | ++ for (i=strlen(line);(line[i-1] == ' '||line[i-1] == '\t')&&i>0; i--) | |
146 | ++ line[i-1] = '\0'; | |
147 | ++ } else | |
148 | ++ line[0] = '\0'; | |
149 | ++ } | |
150 | ++ } | |
151 | ++ for (cp=line; *cp==' '; cp++); | |
152 | ++ | |
153 | ++ if (strlen(cp)) { | |
154 | ++ memcpy(*buf, cp, strlen(cp) >= len ? len-1 : strlen(cp)); | |
155 | ++ return (strlen (cp)); | |
156 | ++ } else | |
157 | ++ return 0; | |
158 | ++} | |
159 | ++ | |
160 | ++#define MAXLINE 100 | |
161 | ++#define PWLEN 20 | |
162 | ++ | |
163 | ++char *getpwline (const char *fname, const char *repository, const char *logname) | |
164 | ++{ | |
165 | ++ FILE *f; | |
166 | ++ char buf[MAXLINE], *bp = buf; | |
167 | ++ static char line[MAXLINE]; | |
168 | ++ int inrepo = 0; | |
169 | ++ char *cp; | |
170 | ++ | |
171 | ++ memset (line, 0, sizeof (line)); | |
172 | ++ | |
173 | ++ if ((f = fopen (fname, "r")) == NULL) { | |
174 | ++ perror ("fopen"); | |
175 | ++ return line; | |
176 | ++ } | |
177 | ++ | |
178 | ++ while (readline (f, &bp, 50)) { | |
179 | ++ if (buf[0] == '/') { | |
180 | ++ syslog(LOG_ERR, "Looking for repo %s in %s\n", repository, buf); | |
181 | ++ if (!inrepo && !strcmp (buf, repository)) | |
182 | ++ { | |
183 | ++ syslog(LOG_ERR, "matched repository %s\n", repository); | |
184 | ++ inrepo = 1; | |
185 | ++ } | |
186 | ++ else if (inrepo) | |
187 | ++ inrepo = 0; | |
188 | ++ } else { | |
189 | ++ if (inrepo) { | |
190 | ++ if ((cp = strchr (buf, ':')) != NULL) { | |
191 | ++ if ( (cp - buf) == strlen (logname) | |
192 | ++ && !strncmp (buf, logname, strlen (logname))) { | |
193 | ++ memcpy (line, buf, strlen(buf) >= MAXLINE ? MAXLINE-1 : strlen(buf)); | |
194 | ++ } | |
195 | ++ } | |
196 | ++ } | |
197 | ++ } | |
198 | ++ } | |
199 | ++ | |
200 | ++ if (ferror (f)) | |
201 | ++ perror ("ferror"); | |
202 | ++ if (fclose (f) < 0) | |
203 | ++ perror ("fclose"); | |
204 | ++ | |
205 | ++ return line; | |
206 | ++} | |
207 | ++ | |
208 | ++/* | |
209 | ++***************************************************************** | |
210 | ++ */ | |
211 | ++#ifdef TEST_READPW | |
212 | ++ | |
213 | ++void getpasswd (const char *fname, const char *repository, const char *logname, char **pw, char **user) | |
214 | ++{ | |
215 | ++ char *line; | |
216 | ++ char *cp, *xp; | |
217 | ++ | |
218 | ++ memset (*pw, 0, PWLEN); | |
219 | ++ memset (*user, 0, PWLEN); | |
220 | ++ | |
221 | ++ line = getpwline(fname, repository, logname); | |
222 | ++ | |
223 | ++ if (line[0] == '\0') | |
224 | ++ return; | |
225 | ++ | |
226 | ++ cp = strchr (line, ':'); | |
227 | ++ cp++; | |
228 | ++ | |
229 | ++ if ((xp = strchr (cp, ':')) != NULL) { | |
230 | ++ memcpy (*pw, cp, xp-cp >= PWLEN ? PWLEN-1 : xp-cp); | |
231 | ++ | |
232 | ++ xp++; | |
233 | ++ | |
234 | ++ if (strlen (xp)) | |
235 | ++ memcpy (*user, xp, strlen(xp) >= PWLEN ? PWLEN-1 : strlen(xp)); | |
236 | ++ } | |
237 | ++} | |
238 | ++ | |
239 | ++int main () | |
240 | ++{ | |
241 | ++ char pw[PWLEN], *ppw = pw; | |
242 | ++ char cvsuser[PWLEN], *pcu = cvsuser; | |
243 | ++ | |
244 | ++ getpasswd (PWFILE, "/cvs/debian-doc", "jseidel", &ppw, &pcu); | |
245 | ++ | |
246 | ++ printf ("%s<:>%s\n", pw, cvsuser); | |
247 | ++ printf ("XXXXXXXXXXXXX\n"); | |
248 | ++ | |
249 | ++ return 0; | |
250 | ++} | |
251 | ++#endif /*TEST_READPW */ | |
252 | +diff -ruN cvs-1.12.13-old/src/server.c cvs-1.12.13/src/server.c | |
253 | +--- cvs-1.12.13-old/src/server.c 2006-08-17 00:25:16.000000000 +0100 | |
254 | ++++ cvs-1.12.13/src/server.c 2006-08-20 00:31:22.000000000 +0100 | |
255 | +@@ -22,6 +22,8 @@ | |
256 | + | |
257 | + int server_active = 0; | |
258 | + | |
259 | ++char *getpwline (const char *fname, const char *repository, const char *logname); | |
260 | ++ | |
261 | + #if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) | |
262 | + | |
263 | + # include "log-buffer.h" | |
264 | +@@ -6689,51 +6691,71 @@ | |
265 | + { | |
266 | + int retval = 0; | |
267 | + FILE *fp; | |
268 | +- char *filename; | |
269 | ++ char *filename = NULL; | |
270 | ++ char *cp; | |
271 | + char *linebuf = NULL; | |
272 | + size_t linebuf_len; | |
273 | + int found_it = 0; | |
274 | + int namelen; | |
275 | + | |
276 | +- /* We don't use current_parsed_root->directory because it hasn't been | |
277 | +- * set yet -- our `repository' argument came from the authentication | |
278 | +- * protocol, not the regular CVS protocol. | |
279 | +- */ | |
280 | +- | |
281 | +- filename = xmalloc (strlen (repository) | |
282 | +- + 1 | |
283 | +- + strlen (CVSROOTADM) | |
284 | +- + 1 | |
285 | +- + strlen (CVSROOTADM_PASSWD) | |
286 | +- + 1); | |
287 | ++ if (!PasswordFileName) | |
288 | ++ { | |
289 | ++ /* We don't use current_parsed_root->directory because it hasn't been | |
290 | ++ * set yet -- our `repository' argument came from the authentication | |
291 | ++ * protocol, not the regular CVS protocol. | |
292 | ++ */ | |
293 | ++ | |
294 | ++ filename = xmalloc (strlen (repository) | |
295 | ++ + 1 | |
296 | ++ + strlen (CVSROOTADM) | |
297 | ++ + 1 | |
298 | ++ + strlen (CVSROOTADM_PASSWD) | |
299 | ++ + 1); | |
300 | + | |
301 | +- (void) sprintf (filename, "%s/%s/%s", repository, | |
302 | +- CVSROOTADM, CVSROOTADM_PASSWD); | |
303 | ++ (void) sprintf (filename, "%s/%s/%s", repository, | |
304 | ++ CVSROOTADM, CVSROOTADM_PASSWD); | |
305 | + | |
306 | +- fp = CVS_FOPEN (filename, "r"); | |
307 | +- if (fp == NULL) | |
308 | +- { | |
309 | +- if (!existence_error (errno)) | |
310 | +- error (0, errno, "cannot open %s", filename); | |
311 | +- free (filename); | |
312 | +- return 0; | |
313 | +- } | |
314 | ++ fp = CVS_FOPEN (filename, "r"); | |
315 | ++ if (fp == NULL) | |
316 | ++ { | |
317 | ++ if (!existence_error (errno)) | |
318 | ++ error (0, errno, "cannot open %s", filename); | |
319 | ++ free (filename); | |
320 | ++ return 0; | |
321 | ++ } | |
322 | + | |
323 | +- /* Look for a relevant line -- one with this user's name. */ | |
324 | +- namelen = strlen (username); | |
325 | +- while (getline (&linebuf, &linebuf_len, fp) >= 0) | |
326 | +- { | |
327 | +- if ((strncmp (linebuf, username, namelen) == 0) | |
328 | +- && (linebuf[namelen] == ':')) | |
329 | +- { | |
330 | +- found_it = 1; | |
331 | +- break; | |
332 | +- } | |
333 | ++ /* Look for a relevant line -- one with this user's name. */ | |
334 | ++ namelen = strlen (username); | |
335 | ++ while (getline (&linebuf, &linebuf_len, fp) >= 0) | |
336 | ++ { | |
337 | ++ if ((strncmp (linebuf, username, namelen) == 0) | |
338 | ++ && (linebuf[namelen] == ':')) | |
339 | ++ { | |
340 | ++ found_it = 1; | |
341 | ++ break; | |
342 | ++ } | |
343 | ++ } | |
344 | ++ if (ferror (fp)) | |
345 | ++ error (0, errno, "cannot read %s", filename); | |
346 | ++ if (fclose (fp) < 0) | |
347 | ++ error (0, errno, "cannot close %s", filename); | |
348 | ++ } | |
349 | ++ else /* DSA_VERSION */ | |
350 | ++ { | |
351 | ++ namelen = strlen (username); | |
352 | ++ | |
353 | ++ cp = getpwline (PasswordFileName, repository, username); | |
354 | ++ /* syslog (LOG_NOTICE, "cp=%s", cp); */ | |
355 | ++ if (strlen (cp)) { | |
356 | ++ linebuf = xmalloc (strlen (cp) + 1); | |
357 | ++ memcpy (linebuf, cp, strlen(cp)+1); | |
358 | ++ /* syslog (LOG_NOTICE, "line=%s", linebuf); */ | |
359 | ++ found_it = 1; | |
360 | ++ } else | |
361 | ++ found_it = 0; | |
362 | ++ | |
363 | ++ /* syslog (LOG_NOTICE, "username=%s, password=%s, repository=%s", username, password, repository); */ | |
364 | + } | |
365 | +- if (ferror (fp)) | |
366 | +- error (0, errno, "cannot read %s", filename); | |
367 | +- if (fclose (fp) < 0) | |
368 | +- error (0, errno, "cannot close %s", filename); | |
369 | + | |
370 | + /* If found_it, then linebuf contains the information we need. */ | |
371 | + if (found_it) | |
372 | +@@ -6823,6 +6845,7 @@ | |
373 | + retval = 0; | |
374 | + } | |
375 | + | |
376 | ++ if (filename) | |
377 | + free (filename); | |
378 | + if (linebuf) | |
379 | + free (linebuf); | |
380 | +@@ -7043,7 +7066,10 @@ | |
381 | + letting you in if it won't say why, and I am not convinced | |
382 | + that the potential information disclosure to an attacker | |
383 | + outweighs this. */ | |
384 | +- printf ("error 0 no such user %s in CVSROOT/passwd\n", username); | |
385 | ++ if (PasswordFileName) | |
386 | ++ printf ("error 0 no such user %s in %s\n", username, PasswordFileName); | |
387 | ++ else | |
388 | ++ printf ("error 0 no such user %s in CVSROOT/passwd\n", username); | |
389 | + | |
390 | + exit (EXIT_FAILURE); | |
391 | + } |