[gq-commit] gq/src configfile.c,1.26,1.27
Status: Beta
Brought to you by:
sur5r
From: <sta...@us...> - 2002-09-18 09:42:16
|
Update of /cvsroot/gqclient/gq/src In directory usw-pr-cvs1:/tmp/cvs-serv2484 Modified Files: configfile.c Log Message: * Fixed a potential buffer overflow situation as indicated by an original source comment of Bert * Modified saving of the condiguration to be robust against problems during writing of the configuration (write to .gq.new, rename .gq.new to .gq). Might need add'l changes to catch all i/o related errors. Index: configfile.c =================================================================== RCS file: /cvsroot/gqclient/gq/src/configfile.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** configfile.c 23 Jul 2002 13:50:06 -0000 1.26 --- configfile.c 18 Sep 2002 09:42:13 -0000 1.27 *************** *** 627,634 **** } ! ! char *filename_config(int context) { ! static char rcpath[128]; char *home; --- 627,636 ---- } ! /* filename_config returns the name of the config file. The returned ! pointer must g_free'd. */ ! gchar *filename_config(int context) { ! gchar *rcpath = NULL; ! /* static char rcpath[128]; */ char *home; *************** *** 639,643 **** } ! snprintf(rcpath, sizeof(rcpath), "%s/%s", home, RCFILE); free(home); --- 641,648 ---- } ! /* need add'l "/", thus add some extra chars */ ! rcpath = g_malloc(strlen(home) + strlen(RCFILE) + 3); ! ! sprintf(rcpath, "%s/%s", home, RCFILE); free(home); *************** *** 668,684 **** config.config_version = CURRENT_CONFIG_VERSION; config.asked_version = CURRENT_CONFIG_VERSION; return; } /* refuse to read config file if world readable (bind passwords) */ ! if( (sfile.st_mode & ~S_IFMT) != 00600 ) { snprintf(errstr, sizeof(errstr), ! _("%s is group and/or world readable.\n" "This file can contain passwords in cleartext,\n" ! "and should be mode 0600.\n\n" "Continuing with default settings...\n"), rcpath); error_push(load_context, errstr); error_flush(load_context); return; } --- 673,691 ---- config.config_version = CURRENT_CONFIG_VERSION; config.asked_version = CURRENT_CONFIG_VERSION; + g_free(rcpath); return; } /* refuse to read config file if world readable (bind passwords) */ ! if( ((sfile.st_mode & ~S_IFMT) & (S_IRWXG|S_IRWXO)) != 0 ) { snprintf(errstr, sizeof(errstr), ! _("%s is group and/or world readable or writeable.\n" "This file can contain passwords in cleartext,\n" ! "and is recommended to have mode 0600.\n\n" "Continuing with default settings...\n"), rcpath); error_push(load_context, errstr); error_flush(load_context); + g_free(rcpath); return; } *************** *** 691,694 **** --- 698,702 ---- fclose(rcfd); } + g_free(rcpath); process_rcfile(rcfile); *************** *** 737,759 **** void config_write_string(struct writeconfig *wc, char *value, char *entity) { ! int i, p; ! char outstr[1024]; ! ! snprintf(outstr, sizeof(outstr), "<%s>", entity); /* quick-and-dirty escape < and > */ for(i = 0; value[i]; i++) { if(value[i] == '<' || value[i] == '>') { ! strcat(outstr, "\\"); /* FIXME: Buffer overflow probs */ } ! p = strlen(outstr); ! outstr[p++] = value[i]; ! outstr[p] = '\0'; } ! strcat(outstr, "</"); ! strcat(outstr, entity); ! strcat(outstr, ">\n"); ! config_write(wc, outstr); } --- 745,764 ---- void config_write_string(struct writeconfig *wc, char *value, char *entity) { ! int i; ! GString *outstr = g_string_sized_new(1024); ! g_string_sprintf(outstr, "<%s>", entity); /* quick-and-dirty escape < and > */ for(i = 0; value[i]; i++) { if(value[i] == '<' || value[i] == '>') { ! g_string_append(outstr, "\\"); } ! g_string_append_c(outstr, value[i]); } ! g_string_append(outstr, "</"); ! g_string_append(outstr, entity); ! g_string_append(outstr, ">\n"); ! config_write(wc, outstr->str); } *************** *** 776,780 **** struct writeconfig *wc; int write_context; ! char *rcpath, errstr[256]; write_context = error_new_context(_("Error writing configfile")); --- 781,788 ---- struct writeconfig *wc; int write_context; ! char *rcpath, errstr[1024]; ! char *tmprcpath; ! struct stat sfile; ! int mode = S_IRUSR|S_IWUSR; write_context = error_new_context(_("Error writing configfile")); *************** *** 796,801 **** return; } ! wc->outfile = fopen(rcpath, "w"); if(!wc->outfile) { snprintf(errstr, sizeof(errstr), --- 804,819 ---- return; } + /* write to temp file... */ + tmprcpath = g_malloc(strlen(rcpath) + 10); + strcpy(tmprcpath, rcpath); + strcat(tmprcpath, ".new"); + + /* check mode of original file. Do not overwrite without write + permission. */ + if(stat(rcpath, &sfile) == 0) { + mode = sfile.st_mode & (S_IRUSR|S_IWUSR); + } ! wc->outfile = fopen(tmprcpath, "w"); if(!wc->outfile) { snprintf(errstr, sizeof(errstr), *************** *** 804,810 **** error_push(write_context, errstr); error_flush(write_context); return; } ! fchmod(fileno(wc->outfile), S_IRUSR|S_IWUSR); config_write(wc, "<?xml version=\"1.0\" standalone=\"yes\"?>\n"); --- 822,830 ---- error_push(write_context, errstr); error_flush(write_context); + g_free(tmprcpath); + g_free(rcpath); return; } ! fchmod(fileno(wc->outfile), mode); config_write(wc, "<?xml version=\"1.0\" standalone=\"yes\"?>\n"); *************** *** 927,932 **** --- 947,968 ---- FREE(wc, "struct writeconfig"); + /* rename temp to final config file */ + + if (rename(tmprcpath, rcpath) != 0) { + snprintf(errstr, sizeof(errstr), + _("Could not replace old configuration (%s) with the new one (%s):\n%s\n"), rcpath, tmprcpath, + strerror(errno)); + error_push(write_context, errstr); + error_flush(write_context); + + g_free(tmprcpath); + g_free(rcpath); + return; + } + error_flush(write_context); + g_free(tmprcpath); + g_free(rcpath); } |