~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to config_file.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

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