mirror of
https://git.FreeBSD.org/ports.git
synced 2025-01-23 09:10:43 +00:00
a6b9b8a7a9
- Improvements to the FreeBSD startup script (Craig Leres) - Minor portability tweak in mmc.c - Fix a potential buffer overrun bug in htpasswd (reported by Alessio Santoru as CVE-2017-17663), no-op on FreeBSD due to our custom patches from Red Hat since r377324 PR: 225701
201 lines
6.2 KiB
C
201 lines
6.2 KiB
C
--- extras/htpasswd.c.orig 2001-12-19 00:08:08 UTC
|
|
+++ extras/htpasswd.c
|
|
@@ -19,7 +19,12 @@
|
|
#define LF 10
|
|
#define CR 13
|
|
|
|
+#define CPW_LEN 13
|
|
+
|
|
+/* ie 'string' + '\0' */
|
|
#define MAX_STRING_LEN 256
|
|
+/* ie 'maxstring' + ':' + cpassword */
|
|
+#define MAX_LINE_LEN MAX_STRING_LEN+1+CPW_LEN
|
|
|
|
int tfd;
|
|
char temp_template[] = "/tmp/htp.XXXXXX";
|
|
@@ -135,8 +140,9 @@ add_password( char* user, FILE* f )
|
|
}
|
|
|
|
static void usage(void) {
|
|
- fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n");
|
|
- fprintf(stderr,"The -c flag creates a new file.\n");
|
|
+ fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n"
|
|
+ "The -c flag creates a new file.\n"
|
|
+ "Will prompt for password, unless given on stdin.\n");
|
|
exit(1);
|
|
}
|
|
|
|
@@ -149,52 +155,129 @@ void interrupted(int signo) {
|
|
int main(int argc, char *argv[]) {
|
|
FILE *tfp,*f;
|
|
char user[MAX_STRING_LEN];
|
|
- char line[MAX_STRING_LEN];
|
|
- char l[MAX_STRING_LEN];
|
|
+ char pwfilename[MAX_STRING_LEN];
|
|
+ char line[MAX_LINE_LEN];
|
|
+ char l[MAX_LINE_LEN];
|
|
char w[MAX_STRING_LEN];
|
|
- char command[MAX_STRING_LEN];
|
|
- int found;
|
|
+ int found,u;
|
|
|
|
tfd = -1;
|
|
+ u = 2; /* argv[u] is username, unless... */
|
|
signal(SIGINT,(void (*)(int))interrupted);
|
|
if(argc == 4) {
|
|
+ u = 3;
|
|
if(strcmp(argv[1],"-c"))
|
|
usage();
|
|
+ if((f=fopen(argv[2],"r")) != NULL) {
|
|
+ fclose(f);
|
|
+ fprintf(stderr,
|
|
+ "Password file %s already exists.\n"
|
|
+ "Delete it first, if you really want to overwrite it.\n",
|
|
+ argv[2]);
|
|
+ exit(1);
|
|
+ }
|
|
+ } else if(argc != 3) usage();
|
|
+ /* check uname length; underlying system will take care of pwdfile
|
|
+ name too long */
|
|
+ if (strlen(argv[u]) >= MAX_STRING_LEN) {
|
|
+ fprintf(stderr,"Username too long (max %i): %s\n",
|
|
+ MAX_STRING_LEN-1, argv[u]);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if(argc == 4) {
|
|
if(!(tfp = fopen(argv[2],"w"))) {
|
|
fprintf(stderr,"Could not open passwd file %s for writing.\n",
|
|
argv[2]);
|
|
perror("fopen");
|
|
exit(1);
|
|
}
|
|
+ if (strlen(argv[2]) > (sizeof(pwfilename) - 1)) {
|
|
+ fprintf(stderr, "%s: filename is too long\n", argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if (((strchr(argv[2], ';')) != NULL) || ((strchr(argv[2], '>')) != NULL)) {
|
|
+ fprintf(stderr, "%s: filename contains an illegal character\n",
|
|
+ argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if (strlen(argv[3]) > (sizeof(user) - 1)) {
|
|
+ fprintf(stderr, "%s: username is too long\n", argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if ((strchr(argv[3], ':')) != NULL) {
|
|
+ fprintf(stderr, "%s: username contains an illegal character\n",
|
|
+ argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
printf("Adding password for %s.\n",argv[3]);
|
|
add_password(argv[3],tfp);
|
|
fclose(tfp);
|
|
exit(0);
|
|
- } else if(argc != 3) usage();
|
|
+ }
|
|
|
|
- tfd = mkstemp(temp_template);
|
|
- if(!(tfp = fdopen(tfd,"w"))) {
|
|
- fprintf(stderr,"Could not open temp file.\n");
|
|
+ if (strlen(argv[1]) > (sizeof(pwfilename) - 1)) {
|
|
+ fprintf(stderr, "%s: filename is too long\n", argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if (((strchr(argv[1], ';')) != NULL) || ((strchr(argv[1], '>')) != NULL)) {
|
|
+ fprintf(stderr, "%s: filename contains an illegal character\n",
|
|
+ argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if (strlen(argv[2]) > (sizeof(user) - 1)) {
|
|
+ fprintf(stderr, "%s: username is too long\n", argv[0]);
|
|
+ exit(1);
|
|
+ }
|
|
+ if ((strchr(argv[2], ':')) != NULL) {
|
|
+ fprintf(stderr, "%s: username contains an illegal character\n",
|
|
+ argv[0]);
|
|
exit(1);
|
|
}
|
|
-
|
|
if(!(f = fopen(argv[1],"r"))) {
|
|
fprintf(stderr,
|
|
"Could not open passwd file %s for reading.\n",argv[1]);
|
|
fprintf(stderr,"Use -c option to create new one.\n");
|
|
exit(1);
|
|
}
|
|
+ if(freopen(argv[1],"a",f) == NULL) {
|
|
+ fprintf(stderr,
|
|
+ "Could not open passwd file %s for writing!.\n"
|
|
+ "Changes would be lost.\n",argv[1]);
|
|
+ exit(1);
|
|
+ }
|
|
+ f = freopen(argv[1],"r",f);
|
|
+
|
|
+ /* pwdfile is there, go on with tempfile now ... */
|
|
+ tfd = mkstemp(temp_template);
|
|
+ if(!(tfp = fdopen(tfd,"w"))) {
|
|
+ fprintf(stderr,"Could not open temp file.\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ /* already checked for boflw ... */
|
|
strncpy(user,argv[2],sizeof(user)-1);
|
|
user[sizeof(user)-1] = '\0';
|
|
|
|
found = 0;
|
|
- while(!(my_getline(line,MAX_STRING_LEN,f))) {
|
|
+ /* line we get is username:pwd, or possibly any other cruft */
|
|
+ while(!(my_getline(line,MAX_LINE_LEN,f))) {
|
|
+ char *i;
|
|
+
|
|
if(found || (line[0] == '#') || (!line[0])) {
|
|
putline(tfp,line);
|
|
continue;
|
|
}
|
|
- strcpy(l,line);
|
|
- getword(w,l,':');
|
|
+ i = index(line,':');
|
|
+ w[0] = '\0';
|
|
+ /* actually, cpw is CPW_LEN chars and never null, hence ':' should
|
|
+ always be at line[strlen(line)-CPW_LEN-1] in a valid user:cpw line
|
|
+ Here though we may allow for pre-hancrafted pwdfile (!)...
|
|
+ But still need to check for length limits.
|
|
+ */
|
|
+ if (i != 0 && i-line <= MAX_STRING_LEN-1) {
|
|
+ strcpy(l,line);
|
|
+ getword(w,l,':');
|
|
+ }
|
|
if(strcmp(user,w)) {
|
|
putline(tfp,line);
|
|
continue;
|
|
@@ -208,10 +291,28 @@ int main(int argc, char *argv[]) {
|
|
printf("Adding user %s\n",user);
|
|
add_password(user,tfp);
|
|
}
|
|
+ /* close, rewind & copy */
|
|
+ fclose(f);
|
|
+ fclose(tfp);
|
|
+ f = fopen(argv[1],"w");
|
|
+ if(f==NULL) {
|
|
+ fprintf(stderr,"Failed re-opening %s!?\n",argv[1]);
|
|
+ exit(1);
|
|
+ }
|
|
+ tfp = fopen(temp_template,"r");
|
|
+ if(tfp==NULL) {
|
|
+ fprintf(stderr,"Failed re-opening tempfile!?\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ {
|
|
+ int c;
|
|
+ while((c=fgetc(tfp))!=EOF && !feof(tfp)) {
|
|
+ fputc(c,f);
|
|
+ /* fputc(c,stderr); */
|
|
+ }
|
|
+ }
|
|
fclose(f);
|
|
fclose(tfp);
|
|
- sprintf(command,"cp %s %s",temp_template,argv[1]);
|
|
- system(command);
|
|
unlink(temp_template);
|
|
exit(0);
|
|
}
|