1 /* $NetBSD: backupsa.c,v 1.8 2006/12/10 18:46:39 manu Exp $ */
3 /* $KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
45 #include <netinet/in.h>
48 #if TIME_WITH_SYS_TIME
49 # include <sys/time.h>
53 # include <sys/time.h>
66 #include "localconf.h"
73 * (time string)%(sa parameter)
74 * (time string) := ex. Nov 24 18:22:48 1986
76 * src dst satype spi mode reqid wsize \
77 * e_type e_keylen a_type a_keylen flags \
78 * l_alloc l_bytes l_addtime l_usetime seq keymat
80 static char *format
= "%b %d %T %Y"; /* time format */
81 static char *strmon
[12] = {
82 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
83 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
86 static char *str2tmx
__P((char *, struct tm
*));
87 static int str2num
__P((char *, int));
90 * output the sa parameter.
93 backupsa_to_file(sa_args
)
94 struct pfkey_send_sa_args
*sa_args
;
108 l
= strftime(p
, len
, format
, tm
);
114 l
= snprintf(p
, len
, "%%");
115 if (l
< 0 || l
>= len
)
122 i
= getnameinfo(sa_args
->src
, sysdep_sa_len(sa_args
->src
), p
, len
, NULL
, 0, NIFLAGS
);
131 l
= snprintf(p
, len
, " ");
132 if (l
< 0 || l
>= len
)
139 i
= getnameinfo(sa_args
->dst
, sysdep_sa_len(sa_args
->dst
), p
, len
, NULL
, 0, NIFLAGS
);
151 "%u %llu %llu %llu %u",
152 sa_args
->satype
, (unsigned long)ntohl(sa_args
->spi
),
153 sa_args
->mode
, sa_args
->reqid
, sa_args
->wsize
, sa_args
->e_type
,
154 sa_args
->e_keylen
, sa_args
->a_type
, sa_args
->a_keylen
,
155 sa_args
->flags
, sa_args
->l_alloc
,
156 (unsigned long long)sa_args
->l_bytes
,
157 (unsigned long long)sa_args
->l_addtime
,
158 (unsigned long long)sa_args
->l_usetime
, sa_args
->seq
);
160 if (l
< 0 || l
>= len
)
167 k
= val2str(sa_args
->keymat
, sa_args
->e_keylen
+ sa_args
->a_keylen
);
168 l
= snprintf(p
, len
, " %s", k
);
170 if (l
< 0 || l
>= len
)
177 /* open the file and write the SA parameter */
178 if (safefile(lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
], 1) != 0 ||
179 (fp
= fopen(lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
], "a")) == NULL
) {
180 plog(LLV_ERROR
, LOCATION
, NULL
,
181 "failed to open the backup file %s.\n",
182 lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
]);
185 fprintf(fp
, "%s\n", buf
);
191 plog(LLV_ERROR
, LOCATION
, NULL
,
192 "SA cannot be saved to a file.\n");
202 time_t created
, current
;
206 struct pfkey_send_sa_args sa_args
;
208 memset(&sa_args
, 0, sizeof(sa_args
));
210 if (safefile(lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
], 1) == 0)
211 fp
= fopen(lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
], "r");
215 plog(LLV_ERROR
, LOCATION
, NULL
,
216 "failed to open the backup file %s.\n",
217 lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
]);
221 current
= time(NULL
);
223 for(line
= 1; fgets(buf
, sizeof(buf
), fp
) != NULL
; line
++) {
228 memset(&tm
, 0, sizeof(tm
));
229 p
= str2tmx(buf
, &tm
);
232 plog(LLV_ERROR
, LOCATION
, NULL
,
233 "illegal format line#%d in %s: %s\n",
234 line
, lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
],
238 created
= mktime(&tm
);
241 for (q
= p
; *q
!= '\0' && !isspace((int)*q
); q
++)
244 if ((sa_args
.src
= str2saddr(p
, NULL
)) == NULL
)
248 for (q
= p
; *q
!= '\0' && !isspace((int)*q
); q
++)
251 if ((sa_args
.dst
= str2saddr(p
, NULL
)) == NULL
)
255 #define GETNEXTNUM(value, function) \
258 for (q = p; *q != '\0' && !isspace((int)*q); q++) \
261 (value) = function(p, &y, 10); \
262 if ((value) == 0 && *y != '\0') \
265 } while (/*CONSTCOND*/0);
267 GETNEXTNUM(sa_args
.satype
, strtoul
);
268 GETNEXTNUM(sa_args
.spi
, strtoul
);
269 sa_args
.spi
= ntohl(sa_args
.spi
);
270 GETNEXTNUM(sa_args
.mode
, strtoul
);
271 GETNEXTNUM(sa_args
.reqid
, strtoul
);
272 GETNEXTNUM(sa_args
.wsize
, strtoul
);
273 GETNEXTNUM(sa_args
.e_type
, strtoul
);
274 GETNEXTNUM(sa_args
.e_keylen
, strtoul
);
275 GETNEXTNUM(sa_args
.a_type
, strtoul
);
276 GETNEXTNUM(sa_args
.a_keylen
, strtoul
);
277 GETNEXTNUM(sa_args
.flags
, strtoul
);
278 GETNEXTNUM(sa_args
.l_alloc
, strtoul
);
279 GETNEXTNUM(sa_args
.l_bytes
, strtouq
);
280 GETNEXTNUM(sa_args
.l_addtime
, strtouq
);
281 GETNEXTNUM(sa_args
.l_usetime
, strtouq
);
282 GETNEXTNUM(sa_args
.seq
, strtoul
);
286 sa_args
.keymat
= str2val(p
, 16, &keymatlen
);
287 if (sa_args
.keymat
== NULL
) {
288 plog(LLV_ERROR
, LOCATION
, NULL
,
289 "illegal format(keymat) line#%d in %s: %s\n",
290 line
, lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
],
295 if (created
+ sa_args
.l_addtime
< current
) {
296 plog(LLV_DEBUG
, LOCATION
, NULL
,
297 "ignore this line#%d in %s due to expiration\n",
298 line
, lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
]);
301 sa_args
.l_addtime
-= current
- created
;
303 if (pfkey_send_add2(&sa_args
) < 0) {
304 plog(LLV_ERROR
, LOCATION
, NULL
,
305 "restore SA failed line#%d in %s: %s\n",
306 line
, lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
],
311 if (sa_args
.src
!= NULL
) {
312 racoon_free(sa_args
.src
);
315 if (sa_args
.dst
!= NULL
) {
316 racoon_free(sa_args
.dst
);
319 if (sa_args
.keymat
!= NULL
) {
320 racoon_free(sa_args
.keymat
);
321 sa_args
.keymat
= NULL
;
328 * There is a possibility that an abnormal system down will happen
329 * again before new negotiation will be started. so racoon clears
330 * the backup file here. it's ok that old SAs are remained in the
331 * file. any old SA will not be installed because racoon checks the
332 * lifetime and compare with current time.
343 /* simply return if the file is not defined. */
344 if (!lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
])
347 fp
= fopen(lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
], "w+");
349 plog(LLV_ERROR
, LOCATION
, NULL
,
350 "failed to clean the backup file %s.\n",
351 lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
]);
359 * convert fixed string into the tm structure.
360 * The fixed string is like 'Nov 24 18:22:48 1986'.
361 * static char *format = "%b %d %T %Y";
364 str2tmx(char *p
, struct tm
*tm
)
369 for (i
= 0; i
< sizeof(strmon
)/sizeof(strmon
[0]); i
++) {
370 if (strncasecmp(p
, strmon
[i
], strlen(strmon
[i
])) == 0) {
375 if (i
== sizeof(strmon
)/sizeof(strmon
[0]))
377 p
+= strlen(strmon
[i
]);
383 tm
->tm_mday
= str2num(p
, len
);
384 if (tm
->tm_mday
== -1 || tm
->tm_mday
> 31)
392 tm
->tm_hour
= str2num(p
, len
);
393 if (tm
->tm_hour
== -1 || tm
->tm_hour
> 24)
401 tm
->tm_min
= str2num(p
, len
);
402 if (tm
->tm_min
== -1 || tm
->tm_min
> 60)
410 tm
->tm_sec
= str2num(p
, len
);
411 if (tm
->tm_sec
== -1 || tm
->tm_sec
> 60)
419 tm
->tm_year
= str2num(p
, len
);
420 if (tm
->tm_year
== -1 || tm
->tm_year
< 1900)
436 for (i
= len
; i
> 0; i
--) {
437 if (!isdigit((int)*p
))
454 char *buf
= "Nov 24 18:22:48 1986 ";
457 memset(&tm
, 0, sizeof(tm
));
458 p
= str2tmx(buf
, &tm
);
459 printf("[%x]\n", *p
);
462 printf("mktime failed.");