]> git.ipfire.org Git - ipfire-2.x.git/blob - src/misc-progs/ipcopbkcfg.c
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[ipfire-2.x.git] / src / misc-progs / ipcopbkcfg.c
1 /*
2 * This file is part of the IPCop Firewall.
3 *
4 * IPCop is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * IPCop is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with IPCop; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Copyright (C) 2003-06-25 Tim Butterfield <timbutterfield@mindspring.com>
19 *
20 * $Id: ipcopbkcfg.c,v 1.2.2.6 2005/11/20 23:20:13 franck78 Exp $
21 *
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <grp.h>
32 #include <dirent.h>
33 #include "setuid.h"
34
35
36 #define EXCLUDE_HARDWARE "exclude.hardware" // exclude file not used on backup but only optionally on restore
37 #define TMP_TAR "/tmp/backup.tar"
38
39 char tempincfilename[STRING_SIZE] = ""; /* temp include file name */
40 char tempexcfilename[STRING_SIZE] = ""; /* temp exclude file name */
41 char temptarfilename[STRING_SIZE] = "";
42
43 /* add fname contents to outfile */
44 void add_file(int outfile, const char *fname, int verbose)
45 {
46 FILE *freadfile;
47 char fbuff[STRING_SIZE];
48
49 if (!(freadfile = fopen(fname, "r"))) {
50 /* skip this file */
51 return;
52 }
53
54 while (fgets(fbuff, STRING_SIZE-1, freadfile) != NULL) {
55 int offset=0;
56 char *ch;
57 char chk_space=1;
58
59 /* trim string in place - don't remove spaces in middle */
60 ch = fbuff;
61 while (*ch) {
62 if (*ch == '\r' || *ch == '\n') {
63 *ch = '\0';
64 }
65
66 if (offset) {
67 *(ch-offset) = *ch;
68 }
69
70 if (*ch == '\t' || *ch == ' ') {
71 if (chk_space) {
72 offset++;
73 }
74 } else {
75 chk_space=0;
76 }
77
78 ch++;
79 }
80
81 /* remove trailing spaces */
82 ch = fbuff + strlen(fbuff) - 1;
83 while (*ch) {
84 if (*ch == '\t' || *ch == ' ') {
85 *ch = '\0';
86 --ch;
87 } else {
88 break;
89 }
90 }
91
92 /* validate name and add it */
93 chdir ("/"); /* support both absolute and relative path */
94 if (*fbuff) {
95 if (file_exists_w(fbuff)) {
96 strcat(fbuff, "\n");
97 write(outfile, fbuff, strlen(fbuff));
98 if (verbose)
99 fprintf(stdout, " %s", fbuff);
100 }
101 }
102 }
103 fclose(freadfile);
104 }
105
106
107 /* combine files starting with fnamebase into outfile */
108 int cmb_files(int outfile, const char *fnamebase, int verbose)
109 {
110 /* scan the directory and add matching files */
111 struct dirent **namelist;
112 int namecount;
113 char addfilename[STRING_SIZE];
114
115 /* scan the directory and get a count of the files */
116 if ((namecount=scandir(CONFIG_ROOT"/backup", &namelist, 0, alphasort))<0) {
117 fprintf(stderr, "No files found\n");
118 exit(1);
119 }
120
121 /* process the scanned names */
122 while (namecount--) {
123 /* check names - compare beginning of name, ignoring case, ignore EXCLUDE_HARDWARE */
124 if ((strncasecmp(fnamebase, namelist[namecount]->d_name, strlen(fnamebase))==0) &&
125 (strncmp(EXCLUDE_HARDWARE,namelist[namecount]->d_name, strlen(EXCLUDE_HARDWARE)))) {
126 /* add the contents for this name to output file */
127 sprintf(addfilename, CONFIG_ROOT"/backup/%s", namelist[namecount]->d_name);
128 if (verbose)
129 fprintf(stdout, "%s\n", namelist[namecount]->d_name);
130 add_file(outfile, addfilename, verbose);
131 free(namelist[namecount]);
132 if (verbose)
133 fprintf(stdout, "\n");
134 }
135 }
136 free(namelist);
137 return 0;
138 }
139
140 void exithandler(void)
141 {
142 /* clean up temporary files */
143 if (temptarfilename)
144 unlink (temptarfilename);
145 if (tempincfilename)
146 unlink (tempincfilename);
147 if (tempexcfilename)
148 unlink (tempexcfilename);
149 }
150
151 int main(int argc, char**argv)
152 {
153 int verbose=0;
154 char command[STRING_SIZE];
155 char hostname[STRING_SIZE];
156 int includefile, excludefile;
157
158 if (!(initsetuid()))
159 exit(1);
160
161 if (argc==2 && strcmp(argv[1],"--verbose")==0)
162 verbose=1; // display to stdout wich (ex|in)clude files are used
163
164 gethostname(hostname, STRING_SIZE-1);
165
166 if (!file_exists(BACKUP_KEY)) {
167 fprintf (stderr, "Couldn't locate encryption key\n");
168 exit (ERR_KEY);
169 }
170
171 /* now exithandler will have something to erase */
172 atexit(exithandler);
173
174 /* combine every include and exclude files in backup directory into two temp file
175 * at the exception of exclude.hardware only used optionally on restore */
176 /* create/open temp output file */
177 // Todo: use -X exclude.files and for include.files, build the list on command line
178 // to avoid unneccesary files manipulations
179 strcpy (tempincfilename, "/tmp/backup-inclusion.XXXXXX");
180 strcpy (tempexcfilename, "/tmp/backup-exclusion.XXXXXX");
181 if ( (!(includefile = mkstemp (tempincfilename)) > 0) ||
182 (!(excludefile = mkstemp (tempexcfilename)) > 0) ){
183 fprintf(stderr, "Couldn't create temporary file.\n");
184 exit(1);
185 }
186 cmb_files(includefile, "include.", verbose);
187 close(includefile);
188 cmb_files(excludefile, "exclude.", verbose);
189 close(excludefile);
190
191 /* Create temporary tarfile */
192 strcpy (temptarfilename, TMP_TAR);
193
194 /* Start tarring files to temp archive
195 W (verify) and z (compress) tar options can't be used together, so separate tar from gzip */
196 snprintf (command, STRING_SIZE-1, "/bin/tar -T %s -X %s -C / -cWf %s > /dev/null 2> /dev/null",
197 tempincfilename, tempexcfilename, temptarfilename);
198 if (safe_system (command)) {
199 fprintf (stderr, "Couldn't create %s file\n", temptarfilename);
200 exit (ERR_TAR);
201 }
202 unlink (tempincfilename);
203 strcpy (tempincfilename,"");
204 unlink (tempexcfilename);
205 strcpy (tempincfilename,"");
206
207 /* Compress archive */
208 snprintf (command, STRING_SIZE-1, "/bin/gzip -c < %s > "MOUNTPOINT"/%s.tar.gz", temptarfilename, hostname);
209 if (safe_system (command)) {
210 fprintf (stderr, "Couldn't create "MOUNTPOINT"%s.tar.gz file\n", hostname);
211 exit (ERR_GZ);
212 }
213 unlink (temptarfilename);
214 strcpy (temptarfilename,"");
215
216 /* Display to stdout include files names */
217 snprintf (command, STRING_SIZE-1, "/bin/tar -ztf "MOUNTPOINT"/%s.tar.gz", hostname);
218 if (safe_system (command)) {
219 fprintf (stderr, "Couldn't read %s.tar.gz file\n", hostname);
220 exit (ERR_TAR);
221 }
222
223 /* Encrypt archive */
224 snprintf (command, STRING_SIZE-1,
225 "/usr/bin/openssl des3 -e -salt -in "MOUNTPOINT"/%s.tar.gz "
226 "-out "MOUNTPOINT"/%s.dat -kfile " BACKUP_KEY, hostname, hostname);
227 if (safe_system (command)) {
228 fprintf (stderr, "Couldn't encrypt archive\n");
229 exit (ERR_ENCRYPT);
230 }
231 snprintf (command, STRING_SIZE-1, MOUNTPOINT"/%s.tar.gz", hostname);
232 unlink (command);
233
234 /* Make sure web can overwrite */
235 snprintf (command, STRING_SIZE-1, MOUNTPOINT"/%s.dat", hostname);
236 chown (command, 99, 99);
237
238 exit(0);
239 }