~ubuntu-branches/ubuntu/precise/wpasupplicant/precise-security

« back to all changes in this revision

Viewing changes to config_file.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2006-10-05 08:04:01 UTC
  • mto: (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20061005080401-vp8camyn71oxw6k7
ImportĀ upstreamĀ versionĀ 0.5.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant / Configuration backend: text file
 
3
 * Copyright (c) 2003-2006, Jouni Malinen <jkmaline@cc.hut.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 *
 
14
 * This file implements a configuration backend for text files. All the
 
15
 * configuration information is stored in a text file that uses a format
 
16
 * described in the sample configuration file, wpa_supplicant.conf.
 
17
 */
 
18
 
 
19
#include "includes.h"
 
20
 
 
21
#include "common.h"
 
22
#include "wpa.h"
 
23
#include "wpa_supplicant.h"
 
24
#include "config.h"
 
25
#include "base64.h"
 
26
#include "eap_methods.h"
 
27
 
 
28
 
 
29
static char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
 
30
                                  char **_pos)
 
31
{
 
32
        char *pos, *end, *sstart;
 
33
 
 
34
        while (fgets(s, size, stream)) {
 
35
                (*line)++;
 
36
                s[size - 1] = '\0';
 
37
                pos = s;
 
38
 
 
39
                while (*pos == ' ' || *pos == '\t' || *pos == '\r')
 
40
                        pos++;
 
41
                if (*pos == '#' || *pos == '\n' || *pos == '\0' ||
 
42
                    *pos == '\r')
 
43
                        continue;
 
44
 
 
45
                /* Remove # comments unless they are within a double quoted
 
46
                 * string. Remove trailing white space. */
 
47
                sstart = strchr(pos, '"');
 
48
                if (sstart)
 
49
                        sstart = strrchr(sstart + 1, '"');
 
50
                if (!sstart)
 
51
                        sstart = pos;
 
52
                end = strchr(sstart, '#');
 
53
                if (end)
 
54
                        *end-- = '\0';
 
55
                else
 
56
                        end = pos + strlen(pos) - 1;
 
57
                while (end > pos &&
 
58
                       (*end == '\n' || *end == ' ' || *end == '\t' ||
 
59
                        *end == '\r')) {
 
60
                        *end-- = '\0';
 
61
                }
 
62
                if (*pos == '\0')
 
63
                        continue;
 
64
 
 
65
                if (_pos)
 
66
                        *_pos = pos;
 
67
                return pos;
 
68
        }
 
69
 
 
70
        if (_pos)
 
71
                *_pos = NULL;
 
72
        return NULL;
 
73
}
 
74
 
 
75
 
 
76
static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id)
 
77
{
 
78
        struct wpa_ssid *ssid;
 
79
        int errors = 0, end = 0;
 
80
        char buf[256], *pos, *pos2;
 
81
 
 
82
        wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block",
 
83
                   *line);
 
84
        ssid = wpa_zalloc(sizeof(*ssid));
 
85
        if (ssid == NULL)
 
86
                return NULL;
 
87
        ssid->id = id;
 
88
 
 
89
        wpa_config_set_network_defaults(ssid);
 
90
 
 
91
        while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
 
92
                if (strcmp(pos, "}") == 0) {
 
93
                        end = 1;
 
94
                        break;
 
95
                }
 
96
 
 
97
                pos2 = strchr(pos, '=');
 
98
                if (pos2 == NULL) {
 
99
                        wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line "
 
100
                                   "'%s'.", *line, pos);
 
101
                        errors++;
 
102
                        continue;
 
103
                }
 
104
 
 
105
                *pos2++ = '\0';
 
106
                if (*pos2 == '"') {
 
107
                        if (strchr(pos2 + 1, '"') == NULL) {
 
108
                                wpa_printf(MSG_ERROR, "Line %d: invalid "
 
109
                                           "quotation '%s'.", *line, pos2);
 
110
                                errors++;
 
111
                                continue;
 
112
                        }
 
113
                }
 
114
 
 
115
                if (wpa_config_set(ssid, pos, pos2, *line) < 0)
 
116
                        errors++;
 
117
        }
 
118
 
 
119
        if (!end) {
 
120
                wpa_printf(MSG_ERROR, "Line %d: network block was not "
 
121
                           "terminated properly.", *line);
 
122
                errors++;
 
123
        }
 
124
 
 
125
        if (ssid->passphrase) {
 
126
                if (ssid->psk_set) {
 
127
                        wpa_printf(MSG_ERROR, "Line %d: both PSK and "
 
128
                                   "passphrase configured.", *line);
 
129
                        errors++;
 
130
                }
 
131
                wpa_config_update_psk(ssid);
 
132
        }
 
133
 
 
134
        if ((ssid->key_mgmt & WPA_KEY_MGMT_PSK) && !ssid->psk_set) {
 
135
                wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key "
 
136
                           "management, but no PSK configured.", *line);
 
137
                errors++;
 
138
        }
 
139
 
 
140
        if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
 
141
            !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
 
142
            !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) {
 
143
                /* Group cipher cannot be stronger than the pairwise cipher. */
 
144
                wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher"
 
145
                           " list since it was not allowed for pairwise "
 
146
                           "cipher", *line);
 
147
                ssid->group_cipher &= ~WPA_CIPHER_CCMP;
 
148
        }
 
149
 
 
150
        if (errors) {
 
151
                wpa_config_free_ssid(ssid);
 
152
                ssid = NULL;
 
153
        }
 
154
 
 
155
        return ssid;
 
156
}
 
157
 
 
158
 
 
159
static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
 
160
                                                     const char *name)
 
161
{
 
162
        struct wpa_config_blob *blob;
 
163
        char buf[256], *pos;
 
164
        unsigned char *encoded = NULL, *nencoded;
 
165
        int end = 0;
 
166
        size_t encoded_len = 0, len;
 
167
 
 
168
        wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'",
 
169
                   *line, name);
 
170
 
 
171
        while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
 
172
                if (strcmp(pos, "}") == 0) {
 
173
                        end = 1;
 
174
                        break;
 
175
                }
 
176
 
 
177
                len = strlen(pos);
 
178
                nencoded = realloc(encoded, encoded_len + len);
 
179
                if (nencoded == NULL) {
 
180
                        wpa_printf(MSG_ERROR, "Line %d: not enough memory for "
 
181
                                   "blob", *line);
 
182
                        free(encoded);
 
183
                        return NULL;
 
184
                }
 
185
                encoded = nencoded;
 
186
                memcpy(encoded + encoded_len, pos, len);
 
187
                encoded_len += len;
 
188
        }
 
189
 
 
190
        if (!end) {
 
191
                wpa_printf(MSG_ERROR, "Line %d: blob was not terminated "
 
192
                           "properly", *line);
 
193
                free(encoded);
 
194
                return NULL;
 
195
        }
 
196
 
 
197
        blob = wpa_zalloc(sizeof(*blob));
 
198
        if (blob == NULL) {
 
199
                free(encoded);
 
200
                return NULL;
 
201
        }
 
202
        blob->name = strdup(name);
 
203
        blob->data = base64_decode(encoded, encoded_len, &blob->len);
 
204
        free(encoded);
 
205
 
 
206
        if (blob->name == NULL || blob->data == NULL) {
 
207
                wpa_config_free_blob(blob);
 
208
                return NULL;
 
209
        }
 
210
 
 
211
        return blob;
 
212
}
 
213
 
 
214
 
 
215
struct wpa_config * wpa_config_read(const char *name)
 
216
{
 
217
        FILE *f;
 
218
        char buf[256], *pos;
 
219
        int errors = 0, line = 0;
 
220
        struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
 
221
        struct wpa_config *config;
 
222
        int id = 0, prio;
 
223
 
 
224
        config = wpa_config_alloc_empty(NULL, NULL);
 
225
        if (config == NULL)
 
226
                return NULL;
 
227
        wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name);
 
228
        f = fopen(name, "r");
 
229
        if (f == NULL) {
 
230
                free(config);
 
231
                return NULL;
 
232
        }
 
233
 
 
234
        while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
 
235
                if (strcmp(pos, "network={") == 0) {
 
236
                        ssid = wpa_config_read_network(f, &line, id++);
 
237
                        if (ssid == NULL) {
 
238
                                wpa_printf(MSG_ERROR, "Line %d: failed to "
 
239
                                           "parse network block.", line);
 
240
                                errors++;
 
241
                                continue;
 
242
                        }
 
243
                        if (head == NULL) {
 
244
                                head = tail = ssid;
 
245
                        } else {
 
246
                                tail->next = ssid;
 
247
                                tail = ssid;
 
248
                        }
 
249
                        if (wpa_config_add_prio_network(config, ssid)) {
 
250
                                wpa_printf(MSG_ERROR, "Line %d: failed to add "
 
251
                                           "network block to priority list.",
 
252
                                           line);
 
253
                                errors++;
 
254
                                continue;
 
255
                        }
 
256
                } else if (strncmp(pos, "blob-base64-", 12) == 0) {
 
257
                        char *name = pos + 12, *name_end;
 
258
                        struct wpa_config_blob *blob;
 
259
 
 
260
                        name_end = strchr(name, '=');
 
261
                        if (name_end == NULL) {
 
262
                                wpa_printf(MSG_ERROR, "Line %d: no blob name "
 
263
                                           "terminator", line);
 
264
                                errors++;
 
265
                                continue;
 
266
                        }
 
267
                        *name_end = '\0';
 
268
 
 
269
                        blob = wpa_config_read_blob(f, &line, name);
 
270
                        if (blob == NULL) {
 
271
                                wpa_printf(MSG_ERROR, "Line %d: failed to read"
 
272
                                           " blob %s", line, name);
 
273
                                errors++;
 
274
                                continue;
 
275
                        }
 
276
                        wpa_config_set_blob(config, blob);
 
277
#ifdef CONFIG_CTRL_IFACE
 
278
                } else if (strncmp(pos, "ctrl_interface=", 15) == 0) {
 
279
                        free(config->ctrl_interface);
 
280
                        config->ctrl_interface = strdup(pos + 15);
 
281
                        wpa_printf(MSG_DEBUG, "ctrl_interface='%s'",
 
282
                                   config->ctrl_interface);
 
283
                } else if (strncmp(pos, "ctrl_interface_group=", 21) == 0) {
 
284
                        free(config->ctrl_interface_group);
 
285
                        config->ctrl_interface_group = strdup(pos + 21);
 
286
                        wpa_printf(MSG_DEBUG, "ctrl_interface_group='%s' "
 
287
                                   "(DEPRECATED)",
 
288
                                   config->ctrl_interface_group);
 
289
#endif /* CONFIG_CTRL_IFACE */
 
290
                } else if (strncmp(pos, "eapol_version=", 14) == 0) {
 
291
                        config->eapol_version = atoi(pos + 14);
 
292
                        if (config->eapol_version < 1 ||
 
293
                            config->eapol_version > 2) {
 
294
                                wpa_printf(MSG_ERROR, "Line %d: Invalid EAPOL "
 
295
                                           "version (%d): '%s'.",
 
296
                                           line, config->eapol_version, pos);
 
297
                                errors++;
 
298
                                continue;
 
299
                        }
 
300
                        wpa_printf(MSG_DEBUG, "eapol_version=%d",
 
301
                                   config->eapol_version);
 
302
                } else if (strncmp(pos, "ap_scan=", 8) == 0) {
 
303
                        config->ap_scan = atoi(pos + 8);
 
304
                        wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan);
 
305
                } else if (strncmp(pos, "fast_reauth=", 12) == 0) {
 
306
                        config->fast_reauth = atoi(pos + 12);
 
307
                        wpa_printf(MSG_DEBUG, "fast_reauth=%d",
 
308
                                   config->fast_reauth);
 
309
                } else if (strncmp(pos, "opensc_engine_path=", 19) == 0) {
 
310
                        free(config->opensc_engine_path);
 
311
                        config->opensc_engine_path = strdup(pos + 19);
 
312
                        wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'",
 
313
                                   config->opensc_engine_path);
 
314
                } else if (strncmp(pos, "pkcs11_engine_path=", 19) == 0) {
 
315
                        free(config->pkcs11_engine_path);
 
316
                        config->pkcs11_engine_path = strdup(pos + 19);
 
317
                        wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'",
 
318
                                   config->pkcs11_engine_path);
 
319
                } else if (strncmp(pos, "pkcs11_module_path=", 19) == 0) {
 
320
                        free(config->pkcs11_module_path);
 
321
                        config->pkcs11_module_path = strdup(pos + 19);
 
322
                        wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'",
 
323
                                   config->pkcs11_module_path);
 
324
                } else if (strncmp(pos, "driver_param=", 13) == 0) {
 
325
                        free(config->driver_param);
 
326
                        config->driver_param = strdup(pos + 13);
 
327
                        wpa_printf(MSG_DEBUG, "driver_param='%s'",
 
328
                                   config->driver_param);
 
329
                } else if (strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) ==
 
330
                           0) {
 
331
                        config->dot11RSNAConfigPMKLifetime = atoi(pos + 27);
 
332
                        wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d",
 
333
                                   config->dot11RSNAConfigPMKLifetime);
 
334
                } else if (strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=",
 
335
                                   34) ==
 
336
                           0) {
 
337
                        config->dot11RSNAConfigPMKReauthThreshold =
 
338
                                atoi(pos + 34);
 
339
                        wpa_printf(MSG_DEBUG,
 
340
                                   "dot11RSNAConfigPMKReauthThreshold=%d",
 
341
                                   config->dot11RSNAConfigPMKReauthThreshold);
 
342
                } else if (strncmp(pos, "dot11RSNAConfigSATimeout=", 25) ==
 
343
                           0) {
 
344
                        config->dot11RSNAConfigSATimeout = atoi(pos + 25);
 
345
                        wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d",
 
346
                                   config->dot11RSNAConfigSATimeout);
 
347
                } else if (strncmp(pos, "update_config=", 14) == 0) {
 
348
                        config->update_config = atoi(pos + 14);
 
349
                        wpa_printf(MSG_DEBUG, "update_config=%d",
 
350
                                   config->update_config);
 
351
                } else if (strncmp(pos, "load_dynamic_eap=", 17) == 0) {
 
352
                        char *so = pos + 17;
 
353
                        int ret;
 
354
                        wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
 
355
                        ret = eap_peer_method_load(so);
 
356
                        if (ret == -2) {
 
357
                                wpa_printf(MSG_DEBUG, "This EAP type was "
 
358
                                           "already loaded - not reloading.");
 
359
                        } else if (ret) {
 
360
                                wpa_printf(MSG_ERROR, "Line %d: Failed to "
 
361
                                           "load dynamic EAP method '%s'.",
 
362
                                           line, so);
 
363
                                errors++;
 
364
                        }
 
365
                } else {
 
366
                        wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
 
367
                                   "line '%s'.", line, pos);
 
368
                        errors++;
 
369
                        continue;
 
370
                }
 
371
        }
 
372
 
 
373
        fclose(f);
 
374
 
 
375
        config->ssid = head;
 
376
        for (prio = 0; prio < config->num_prio; prio++) {
 
377
                ssid = config->pssid[prio];
 
378
                wpa_printf(MSG_DEBUG, "Priority group %d",
 
379
                           ssid->priority);
 
380
                while (ssid) {
 
381
                        wpa_printf(MSG_DEBUG, "   id=%d ssid='%s'",
 
382
                                   ssid->id,
 
383
                                   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
 
384
                        ssid = ssid->pnext;
 
385
                }
 
386
        }
 
387
        if (errors) {
 
388
                wpa_config_free(config);
 
389
                config = NULL;
 
390
                head = NULL;
 
391
        }
 
392
 
 
393
        return config;
 
394
}
 
395
 
 
396
 
 
397
static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
 
398
{
 
399
        char *value = wpa_config_get(ssid, field);
 
400
        if (value == NULL)
 
401
                return;
 
402
        fprintf(f, "\t%s=%s\n", field, value);
 
403
        free(value);
 
404
}
 
405
 
 
406
 
 
407
static void write_int(FILE *f, const char *field, int value, int def)
 
408
{
 
409
        if (value == def)
 
410
                return;
 
411
        fprintf(f, "\t%s=%d\n", field, value);
 
412
}
 
413
 
 
414
 
 
415
static void write_bssid(FILE *f, struct wpa_ssid *ssid)
 
416
{
 
417
        char *value = wpa_config_get(ssid, "bssid");
 
418
        if (value == NULL)
 
419
                return;
 
420
        fprintf(f, "\tbssid=%s\n", value);
 
421
        free(value);
 
422
}
 
423
 
 
424
 
 
425
static void write_psk(FILE *f, struct wpa_ssid *ssid)
 
426
{
 
427
        char *value = wpa_config_get(ssid, "psk");
 
428
        if (value == NULL)
 
429
                return;
 
430
        fprintf(f, "\tpsk=%s\n", value);
 
431
        free(value);
 
432
}
 
433
 
 
434
 
 
435
static void write_proto(FILE *f, struct wpa_ssid *ssid)
 
436
{
 
437
        char *value;
 
438
 
 
439
        if (ssid->proto == DEFAULT_PROTO)
 
440
                return;
 
441
 
 
442
        value = wpa_config_get(ssid, "proto");
 
443
        if (value == NULL)
 
444
                return;
 
445
        if (value[0])
 
446
                fprintf(f, "\tproto=%s\n", value);
 
447
        free(value);
 
448
}
 
449
 
 
450
 
 
451
static void write_key_mgmt(FILE *f, struct wpa_ssid *ssid)
 
452
{
 
453
        char *value;
 
454
 
 
455
        if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
 
456
                return;
 
457
 
 
458
        value = wpa_config_get(ssid, "key_mgmt");
 
459
        if (value == NULL)
 
460
                return;
 
461
        if (value[0])
 
462
                fprintf(f, "\tkey_mgmt=%s\n", value);
 
463
        free(value);
 
464
}
 
465
 
 
466
 
 
467
static void write_pairwise(FILE *f, struct wpa_ssid *ssid)
 
468
{
 
469
        char *value;
 
470
 
 
471
        if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
 
472
                return;
 
473
 
 
474
        value = wpa_config_get(ssid, "pairwise");
 
475
        if (value == NULL)
 
476
                return;
 
477
        if (value[0])
 
478
                fprintf(f, "\tpairwise=%s\n", value);
 
479
        free(value);
 
480
}
 
481
 
 
482
 
 
483
static void write_group(FILE *f, struct wpa_ssid *ssid)
 
484
{
 
485
        char *value;
 
486
 
 
487
        if (ssid->group_cipher == DEFAULT_GROUP)
 
488
                return;
 
489
 
 
490
        value = wpa_config_get(ssid, "group");
 
491
        if (value == NULL)
 
492
                return;
 
493
        if (value[0])
 
494
                fprintf(f, "\tgroup=%s\n", value);
 
495
        free(value);
 
496
}
 
497
 
 
498
 
 
499
static void write_auth_alg(FILE *f, struct wpa_ssid *ssid)
 
500
{
 
501
        char *value;
 
502
 
 
503
        if (ssid->auth_alg == 0)
 
504
                return;
 
505
 
 
506
        value = wpa_config_get(ssid, "auth_alg");
 
507
        if (value == NULL)
 
508
                return;
 
509
        if (value[0])
 
510
                fprintf(f, "\tauth_alg=%s\n", value);
 
511
        free(value);
 
512
}
 
513
 
 
514
 
 
515
#ifdef IEEE8021X_EAPOL
 
516
static void write_eap(FILE *f, struct wpa_ssid *ssid)
 
517
{
 
518
        char *value;
 
519
 
 
520
        value = wpa_config_get(ssid, "eap");
 
521
        if (value == NULL)
 
522
                return;
 
523
 
 
524
        if (value[0])
 
525
                fprintf(f, "\teap=%s\n", value);
 
526
        free(value);
 
527
}
 
528
#endif /* IEEE8021X_EAPOL */
 
529
 
 
530
 
 
531
static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
 
532
{
 
533
        char field[20], *value;
 
534
 
 
535
        snprintf(field, sizeof(field), "wep_key%d", idx);
 
536
        value = wpa_config_get(ssid, field);
 
537
        if (value) {
 
538
                fprintf(f, "\t%s=%s\n", field, value);
 
539
                free(value);
 
540
        }
 
541
}
 
542
 
 
543
 
 
544
static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 
545
{
 
546
        int i;
 
547
 
 
548
#define STR(t) write_str(f, #t, ssid)
 
549
#define INT(t) write_int(f, #t, ssid->t, 0)
 
550
#define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
 
551
 
 
552
        STR(ssid);
 
553
        INT(scan_ssid);
 
554
        write_bssid(f, ssid);
 
555
        write_psk(f, ssid);
 
556
        write_proto(f, ssid);
 
557
        write_key_mgmt(f, ssid);
 
558
        write_pairwise(f, ssid);
 
559
        write_group(f, ssid);
 
560
        write_auth_alg(f, ssid);
 
561
#ifdef IEEE8021X_EAPOL
 
562
        write_eap(f, ssid);
 
563
        STR(identity);
 
564
        STR(anonymous_identity);
 
565
        STR(eappsk);
 
566
        STR(nai);
 
567
        STR(password);
 
568
        STR(ca_cert);
 
569
        STR(client_cert);
 
570
        STR(private_key);
 
571
        STR(private_key_passwd);
 
572
        STR(dh_file);
 
573
        STR(subject_match);
 
574
        STR(altsubject_match);
 
575
        STR(ca_cert2);
 
576
        STR(client_cert2);
 
577
        STR(private_key2);
 
578
        STR(private_key2_passwd);
 
579
        STR(dh_file2);
 
580
        STR(subject_match2);
 
581
        STR(altsubject_match2);
 
582
        STR(phase1);
 
583
        STR(phase2);
 
584
        STR(pcsc);
 
585
        STR(pin);
 
586
        STR(engine_id);
 
587
        STR(key_id);
 
588
        INT(engine);
 
589
        INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
 
590
#endif /* IEEE8021X_EAPOL */
 
591
        for (i = 0; i < 4; i++)
 
592
                write_wep_key(f, i, ssid);
 
593
        INT(wep_tx_keyidx);
 
594
        INT(priority);
 
595
#ifdef IEEE8021X_EAPOL
 
596
        INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
 
597
        STR(pac_file);
 
598
        INT_DEF(fragment_size, DEFAULT_FRAGMENT_SIZE);
 
599
#endif /* IEEE8021X_EAPOL */
 
600
        INT(mode);
 
601
        INT(proactive_key_caching);
 
602
        INT(disabled);
 
603
        INT(stakey);
 
604
        INT(peerkey);
 
605
        STR(id_str);
 
606
 
 
607
#undef STR
 
608
#undef INT
 
609
#undef INT_DEF
 
610
}
 
611
 
 
612
 
 
613
static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob)
 
614
{
 
615
        unsigned char *encoded;
 
616
 
 
617
        encoded = base64_encode(blob->data, blob->len, NULL);
 
618
        if (encoded == NULL)
 
619
                return -1;
 
620
 
 
621
        fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded);
 
622
        free(encoded);
 
623
        return 0;
 
624
}
 
625
 
 
626
 
 
627
int wpa_config_write(const char *name, struct wpa_config *config)
 
628
{
 
629
        FILE *f;
 
630
        struct wpa_ssid *ssid;
 
631
        struct wpa_config_blob *blob;
 
632
        int ret = 0;
 
633
 
 
634
        wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
 
635
 
 
636
 
 
637
        f = fopen(name, "w");
 
638
        if (f == NULL) {
 
639
                wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name);
 
640
                return -1;
 
641
        }
 
642
 
 
643
#ifdef CONFIG_CTRL_IFACE
 
644
        if (config->ctrl_interface)
 
645
                fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface);
 
646
        if (config->ctrl_interface_group)
 
647
                fprintf(f, "ctrl_interface_group=%s\n",
 
648
                        config->ctrl_interface_group);
 
649
#endif /* CONFIG_CTRL_IFACE */
 
650
        if (config->eapol_version != DEFAULT_EAPOL_VERSION)
 
651
                fprintf(f, "eapol_version=%d\n", config->eapol_version);
 
652
        if (config->ap_scan != DEFAULT_AP_SCAN)
 
653
                fprintf(f, "ap_scan=%d\n", config->ap_scan);
 
654
        if (config->fast_reauth != DEFAULT_FAST_REAUTH)
 
655
                fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
 
656
        if (config->opensc_engine_path)
 
657
                fprintf(f, "opensc_engine_path=%s\n",
 
658
                        config->opensc_engine_path);
 
659
        if (config->pkcs11_engine_path)
 
660
                fprintf(f, "pkcs11_engine_path=%s\n",
 
661
                        config->pkcs11_engine_path);
 
662
        if (config->pkcs11_module_path)
 
663
                fprintf(f, "pkcs11_module_path=%s\n",
 
664
                        config->pkcs11_module_path);
 
665
        if (config->driver_param)
 
666
                fprintf(f, "driver_param=%s\n", config->driver_param);
 
667
        if (config->dot11RSNAConfigPMKLifetime)
 
668
                fprintf(f, "dot11RSNAConfigPMKLifetime=%d\n",
 
669
                        config->dot11RSNAConfigPMKLifetime);
 
670
        if (config->dot11RSNAConfigPMKReauthThreshold)
 
671
                fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%d\n",
 
672
                        config->dot11RSNAConfigPMKReauthThreshold);
 
673
        if (config->dot11RSNAConfigSATimeout)
 
674
                fprintf(f, "dot11RSNAConfigSATimeout=%d\n",
 
675
                        config->dot11RSNAConfigSATimeout);
 
676
        if (config->update_config)
 
677
                fprintf(f, "update_config=%d\n", config->update_config);
 
678
 
 
679
        for (ssid = config->ssid; ssid; ssid = ssid->next) {
 
680
                fprintf(f, "\nnetwork={\n");
 
681
                wpa_config_write_network(f, ssid);
 
682
                fprintf(f, "}\n");
 
683
        }
 
684
 
 
685
        for (blob = config->blobs; blob; blob = blob->next) {
 
686
                ret = wpa_config_write_blob(f, blob);
 
687
                if (ret)
 
688
                        break;
 
689
        }
 
690
 
 
691
        fclose(f);
 
692
 
 
693
        wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
 
694
                   name, ret ? "un" : "");
 
695
        return ret;
 
696
}