pluto and scepclient now use chunk_t from libstrongswan
[strongswan.git] / src / pluto / defs.c
1 /* misc. universal things
2 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * RCSID $Id$
15 */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <dirent.h>
21 #include <time.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include <freeswan.h>
26
27 #include "constants.h"
28 #include "defs.h"
29 #include "log.h"
30 #include "whack.h" /* for RC_LOG_SERIOUS */
31
32 bool
33 all_zero(const unsigned char *m, size_t len)
34 {
35 size_t i;
36
37 for (i = 0; i != len; i++)
38 if (m[i] != '\0')
39 return FALSE;
40 return TRUE;
41 }
42
43 void *clone_bytes(const void *orig, size_t size)
44 {
45 void *p = malloc(size);
46
47 memcpy(p, orig, size);
48 return p;
49 }
50
51 /* Note that there may be as many as six IDs that are temporary at
52 * one time before unsharing the two ends of a connection. So we need
53 * at least six temporary buffers for DER_ASN1_DN IDs.
54 * We rotate them. Be careful!
55 */
56 #define MAX_BUF 10
57
58 char*
59 temporary_cyclic_buffer(void)
60 {
61 static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
62 static int counter = 0; /* cyclic counter */
63
64 if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
65 return buf[counter]; /* assign temporary buffer */
66 }
67
68 /* concatenates two sub paths into a string with a maximum size of BUF_LEN
69 * use for temporary storage only
70 */
71 const char*
72 concatenate_paths(const char *a, const char *b)
73 {
74 char *c;
75
76 if (*b == '/' || *b == '.')
77 return b;
78
79 c = temporary_cyclic_buffer();
80 snprintf(c, BUF_LEN, "%s/%s", a, b);
81 return c;
82 }
83
84 /* moves a chunk to a memory position, chunk is freed afterwards
85 * position pointer is advanced after the insertion point
86 */
87 void
88 mv_chunk(u_char **pos, chunk_t content)
89 {
90 if (content.len > 0)
91 {
92 chunkcpy(*pos, content);
93 free(content.ptr);
94 }
95 }
96
97 /*
98 * write the binary contents of a chunk_t to a file
99 */
100 bool
101 write_chunk(const char *filename, const char *label, chunk_t ch
102 , mode_t mask, bool force)
103 {
104 mode_t oldmask;
105 FILE *fd;
106 size_t written;
107
108 if (!force)
109 {
110 fd = fopen(filename, "r");
111 if (fd)
112 {
113 fclose(fd);
114 plog(" %s file '%s' already exists", label, filename);
115 return FALSE;
116 }
117 }
118
119 /* set umask */
120 oldmask = umask(mask);
121
122 fd = fopen(filename, "w");
123
124 if (fd)
125 {
126 written = fwrite(ch.ptr, sizeof(u_char), ch.len, fd);
127 fclose(fd);
128 if (written != ch.len)
129 {
130 plog(" writing to %s file '%s' failed", label, filename);
131 umask(oldmask);
132 return FALSE;
133 }
134 plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
135 umask(oldmask);
136 return TRUE;
137 }
138 else
139 {
140 plog(" could not open %s file '%s' for writing", label, filename);
141 umask(oldmask);
142 return FALSE;
143 }
144 }
145
146 /* Names of the months */
147
148 static const char* months[] = {
149 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
150 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
151 };
152
153
154 /*
155 * Display a date either in local or UTC time
156 */
157 char*
158 timetoa(const time_t *time, bool utc)
159 {
160 static char buf[TIMETOA_BUF];
161
162 if (*time == UNDEFINED_TIME)
163 sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
164 else
165 {
166 struct tm *t = (utc)? gmtime(time) : localtime(time);
167
168 sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
169 months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
170 (utc)?" UTC ":" ", t->tm_year + 1900
171 );
172 }
173 return buf;
174 }
175
176 /* checks if the expiration date has been reached and
177 * warns during the warning_interval of the imminent
178 * expiry. strict=TRUE declares a fatal error,
179 * strict=FALSE issues a warning upon expiry.
180 */
181 const char*
182 check_expiry(time_t expiration_date, int warning_interval, bool strict)
183 {
184 time_t now;
185 int time_left;
186
187 if (expiration_date == UNDEFINED_TIME)
188 return "ok (expires never)";
189
190 /* determine the current time */
191 time(&now);
192
193 time_left = (expiration_date - now);
194 if (time_left < 0)
195 return strict? "fatal (expired)" : "warning (expired)";
196
197 if (time_left > 86400*warning_interval)
198 return "ok";
199 {
200 static char buf[35]; /* temporary storage */
201 const char* unit = "second";
202
203 if (time_left > 172800)
204 {
205 time_left /= 86400;
206 unit = "day";
207 }
208 else if (time_left > 7200)
209 {
210 time_left /= 3600;
211 unit = "hour";
212 }
213 else if (time_left > 120)
214 {
215 time_left /= 60;
216 unit = "minute";
217 }
218 snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
219 unit, (time_left == 1)?"":"s");
220 return buf;
221 }
222 }
223
224
225 /*
226 * Filter eliminating the directory entries '.' and '..'
227 */
228 int
229 file_select(const struct dirent *entry)
230 {
231 return strcmp(entry->d_name, "." ) &&
232 strcmp(entry->d_name, "..");
233 }
234
235