config_file.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant / Configuration backend: text file
00003  * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  *
00014  * This file implements a configuration backend for text files. All the
00015  * configuration information is stored in a text file that uses a format
00016  * described in the sample configuration file, wpa_supplicant.conf.
00017  */
00018 
00019 #include "includes.h"
00020 
00021 #include "common.h"
00022 #include "config.h"
00023 #include "base64.h"
00024 #include "uuid.h"
00025 #include "eap_peer/eap_methods.h"
00026 
00027 
00042 static char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
00043                                   char **_pos)
00044 {
00045         char *pos, *end, *sstart;
00046 
00047         while (fgets(s, size, stream)) {
00048                 (*line)++;
00049                 s[size - 1] = '\0';
00050                 pos = s;
00051 
00052                 /* Skip white space from the beginning of line. */
00053                 while (*pos == ' ' || *pos == '\t' || *pos == '\r')
00054                         pos++;
00055 
00056                 /* Skip comment lines and empty lines */
00057                 if (*pos == '#' || *pos == '\n' || *pos == '\0')
00058                         continue;
00059 
00060                 /*
00061                  * Remove # comments unless they are within a double quoted
00062                  * string.
00063                  */
00064                 sstart = os_strchr(pos, '"');
00065                 if (sstart)
00066                         sstart = os_strrchr(sstart + 1, '"');
00067                 if (!sstart)
00068                         sstart = pos;
00069                 end = os_strchr(sstart, '#');
00070                 if (end)
00071                         *end-- = '\0';
00072                 else
00073                         end = pos + os_strlen(pos) - 1;
00074 
00075                 /* Remove trailing white space. */
00076                 while (end > pos &&
00077                        (*end == '\n' || *end == ' ' || *end == '\t' ||
00078                         *end == '\r'))
00079                         *end-- = '\0';
00080 
00081                 if (*pos == '\0')
00082                         continue;
00083 
00084                 if (_pos)
00085                         *_pos = pos;
00086                 return pos;
00087         }
00088 
00089         if (_pos)
00090                 *_pos = NULL;
00091         return NULL;
00092 }
00093 
00094 
00095 static int wpa_config_validate_network(struct wpa_ssid *ssid, int line)
00096 {
00097         int errors = 0;
00098 
00099         if (ssid->passphrase) {
00100                 if (ssid->psk_set) {
00101                         wpa_printf(MSG_ERROR, "Line %d: both PSK and "
00102                                    "passphrase configured.", line);
00103                         errors++;
00104                 }
00105                 wpa_config_update_psk(ssid);
00106         }
00107 
00108         if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
00109                                WPA_KEY_MGMT_PSK_SHA256)) &&
00110             !ssid->psk_set) {
00111                 wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key "
00112                            "management, but no PSK configured.", line);
00113                 errors++;
00114         }
00115 
00116         if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
00117             !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
00118             !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) {
00119                 /* Group cipher cannot be stronger than the pairwise cipher. */
00120                 wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher"
00121                            " list since it was not allowed for pairwise "
00122                            "cipher", line);
00123                 ssid->group_cipher &= ~WPA_CIPHER_CCMP;
00124         }
00125 
00126         return errors;
00127 }
00128 
00129 
00130 static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id)
00131 {
00132         struct wpa_ssid *ssid;
00133         int errors = 0, end = 0;
00134         char buf[256], *pos, *pos2;
00135 
00136         wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block",
00137                    *line);
00138         ssid = os_zalloc(sizeof(*ssid));
00139         if (ssid == NULL)
00140                 return NULL;
00141         ssid->id = id;
00142 
00143         wpa_config_set_network_defaults(ssid);
00144 
00145         while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
00146                 if (os_strcmp(pos, "}") == 0) {
00147                         end = 1;
00148                         break;
00149                 }
00150 
00151                 pos2 = os_strchr(pos, '=');
00152                 if (pos2 == NULL) {
00153                         wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line "
00154                                    "'%s'.", *line, pos);
00155                         errors++;
00156                         continue;
00157                 }
00158 
00159                 *pos2++ = '\0';
00160                 if (*pos2 == '"') {
00161                         if (os_strchr(pos2 + 1, '"') == NULL) {
00162                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
00163                                            "quotation '%s'.", *line, pos2);
00164                                 errors++;
00165                                 continue;
00166                         }
00167                 }
00168 
00169                 if (wpa_config_set(ssid, pos, pos2, *line) < 0)
00170                         errors++;
00171         }
00172 
00173         if (!end) {
00174                 wpa_printf(MSG_ERROR, "Line %d: network block was not "
00175                            "terminated properly.", *line);
00176                 errors++;
00177         }
00178 
00179         errors += wpa_config_validate_network(ssid, *line);
00180 
00181         if (errors) {
00182                 wpa_config_free_ssid(ssid);
00183                 ssid = NULL;
00184         }
00185 
00186         return ssid;
00187 }
00188 
00189 
00190 #ifndef CONFIG_NO_CONFIG_BLOBS
00191 static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
00192                                                      const char *name)
00193 {
00194         struct wpa_config_blob *blob;
00195         char buf[256], *pos;
00196         unsigned char *encoded = NULL, *nencoded;
00197         int end = 0;
00198         size_t encoded_len = 0, len;
00199 
00200         wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'",
00201                    *line, name);
00202 
00203         while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
00204                 if (os_strcmp(pos, "}") == 0) {
00205                         end = 1;
00206                         break;
00207                 }
00208 
00209                 len = os_strlen(pos);
00210                 nencoded = os_realloc(encoded, encoded_len + len);
00211                 if (nencoded == NULL) {
00212                         wpa_printf(MSG_ERROR, "Line %d: not enough memory for "
00213                                    "blob", *line);
00214                         os_free(encoded);
00215                         return NULL;
00216                 }
00217                 encoded = nencoded;
00218                 os_memcpy(encoded + encoded_len, pos, len);
00219                 encoded_len += len;
00220         }
00221 
00222         if (!end) {
00223                 wpa_printf(MSG_ERROR, "Line %d: blob was not terminated "
00224                            "properly", *line);
00225                 os_free(encoded);
00226                 return NULL;
00227         }
00228 
00229         blob = os_zalloc(sizeof(*blob));
00230         if (blob == NULL) {
00231                 os_free(encoded);
00232                 return NULL;
00233         }
00234         blob->name = os_strdup(name);
00235         blob->data = base64_decode(encoded, encoded_len, &blob->len);
00236         os_free(encoded);
00237 
00238         if (blob->name == NULL || blob->data == NULL) {
00239                 wpa_config_free_blob(blob);
00240                 return NULL;
00241         }
00242 
00243         return blob;
00244 }
00245 
00246 
00247 static int wpa_config_process_blob(struct wpa_config *config, FILE *f,
00248                                    int *line, char *bname)
00249 {
00250         char *name_end;
00251         struct wpa_config_blob *blob;
00252 
00253         name_end = os_strchr(bname, '=');
00254         if (name_end == NULL) {
00255                 wpa_printf(MSG_ERROR, "Line %d: no blob name terminator",
00256                            *line);
00257                 return -1;
00258         }
00259         *name_end = '\0';
00260 
00261         blob = wpa_config_read_blob(f, line, bname);
00262         if (blob == NULL) {
00263                 wpa_printf(MSG_ERROR, "Line %d: failed to read blob %s",
00264                            *line, bname);
00265                 return -1;
00266         }
00267         wpa_config_set_blob(config, blob);
00268         return 0;
00269 }
00270 #endif /* CONFIG_NO_CONFIG_BLOBS */
00271 
00272 
00273 struct global_parse_data {
00274         char *name;
00275         int (*parser)(const struct global_parse_data *data,
00276                       struct wpa_config *config, int line, const char *value);
00277         void *param1, *param2, *param3;
00278 };
00279 
00280 
00281 static int wpa_config_parse_int(const struct global_parse_data *data,
00282                                 struct wpa_config *config, int line,
00283                                 const char *pos)
00284 {
00285         int *dst;
00286         dst = (int *) (((u8 *) config) + (long) data->param1);
00287         *dst = atoi(pos);
00288         wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
00289 
00290         if (data->param2 && *dst < (long) data->param2) {
00291                 wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
00292                            "min_value=%ld)", line, data->name, *dst,
00293                            (long) data->param2);
00294                 *dst = (long) data->param2;
00295                 return -1;
00296         }
00297 
00298         if (data->param3 && *dst > (long) data->param3) {
00299                 wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
00300                            "max_value=%ld)", line, data->name, *dst,
00301                            (long) data->param3);
00302                 *dst = (long) data->param3;
00303                 return -1;
00304         }
00305 
00306         return 0;
00307 }
00308 
00309 
00310 static int wpa_config_parse_str(const struct global_parse_data *data,
00311                                 struct wpa_config *config, int line,
00312                                 const char *pos)
00313 {
00314         size_t len;
00315         char **dst, *tmp;
00316 
00317         len = os_strlen(pos);
00318         if (data->param2 && len < (size_t) data->param2) {
00319                 wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
00320                            "min_len=%ld)", line, data->name,
00321                            (unsigned long) len, (long) data->param2);
00322                 return -1;
00323         }
00324 
00325         if (data->param3 && len > (size_t) data->param3) {
00326                 wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
00327                            "max_len=%ld)", line, data->name,
00328                            (unsigned long) len, (long) data->param3);
00329                 return -1;
00330         }
00331 
00332         tmp = os_strdup(pos);
00333         if (tmp == NULL)
00334                 return -1;
00335 
00336         dst = (char **) (((u8 *) config) + (long) data->param1);
00337         os_free(*dst);
00338         *dst = tmp;
00339         wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
00340 
00341         return 0;
00342 }
00343 
00344 
00345 static int wpa_config_process_country(const struct global_parse_data *data,
00346                                       struct wpa_config *config, int line,
00347                                       const char *pos)
00348 {
00349         if (!pos[0] || !pos[1]) {
00350                 wpa_printf(MSG_DEBUG, "Invalid country set");
00351                 return -1;
00352         }
00353         config->country[0] = pos[0];
00354         config->country[1] = pos[1];
00355         wpa_printf(MSG_DEBUG, "country='%c%c'",
00356                    config->country[0], config->country[1]);
00357         return 0;
00358 }
00359 
00360 
00361 static int wpa_config_process_load_dynamic_eap(
00362         const struct global_parse_data *data, struct wpa_config *config,
00363         int line, const char *so)
00364 {
00365         int ret;
00366         wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
00367         ret = eap_peer_method_load(so);
00368         if (ret == -2) {
00369                 wpa_printf(MSG_DEBUG, "This EAP type was already loaded - not "
00370                            "reloading.");
00371         } else if (ret) {
00372                 wpa_printf(MSG_ERROR, "Line %d: Failed to load dynamic EAP "
00373                            "method '%s'.", line, so);
00374                 return -1;
00375         }
00376 
00377         return 0;
00378 }
00379 
00380 
00381 #ifdef CONFIG_WPS
00382 
00383 static int wpa_config_process_uuid(const struct global_parse_data *data,
00384                                    struct wpa_config *config, int line,
00385                                    const char *pos)
00386 {
00387         char buf[40];
00388         if (uuid_str2bin(pos, config->uuid)) {
00389                 wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
00390                 return -1;
00391         }
00392         uuid_bin2str(config->uuid, buf, sizeof(buf));
00393         wpa_printf(MSG_DEBUG, "uuid=%s", buf);
00394         return 0;
00395 }
00396 
00397 
00398 static int wpa_config_process_os_version(const struct global_parse_data *data,
00399                                          struct wpa_config *config, int line,
00400                                          const char *pos)
00401 {
00402         if (hexstr2bin(pos, config->os_version, 4)) {
00403                 wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
00404                 return -1;
00405         }
00406         wpa_printf(MSG_DEBUG, "os_version=%08x",
00407                    WPA_GET_BE32(config->os_version));
00408         return 0;
00409 }
00410 
00411 #endif /* CONFIG_WPS */
00412 
00413 
00414 #ifdef OFFSET
00415 #undef OFFSET
00416 #endif /* OFFSET */
00417 /* OFFSET: Get offset of a variable within the wpa_config structure */
00418 #define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
00419 
00420 #define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
00421 #define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
00422 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f)
00423 #define INT(f) _INT(f), NULL, NULL
00424 #define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
00425 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
00426 #define STR(f) _STR(f), NULL, NULL
00427 #define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
00428 
00429 static const struct global_parse_data global_fields[] = {
00430 #ifdef CONFIG_CTRL_IFACE
00431         { STR(ctrl_interface) },
00432         { STR(ctrl_interface_group) } /* deprecated */,
00433 #endif /* CONFIG_CTRL_IFACE */
00434         { INT_RANGE(eapol_version, 1, 2) },
00435         { INT(ap_scan) },
00436         { INT(fast_reauth) },
00437         { STR(opensc_engine_path) },
00438         { STR(pkcs11_engine_path) },
00439         { STR(pkcs11_module_path) },
00440         { STR(driver_param) },
00441         { INT(dot11RSNAConfigPMKLifetime) },
00442         { INT(dot11RSNAConfigPMKReauthThreshold) },
00443         { INT(dot11RSNAConfigSATimeout) },
00444 #ifndef CONFIG_NO_CONFIG_WRITE
00445         { INT(update_config) },
00446 #endif /* CONFIG_NO_CONFIG_WRITE */
00447         { FUNC_NO_VAR(load_dynamic_eap) },
00448 #ifdef CONFIG_WPS
00449         { FUNC(uuid) },
00450         { STR_RANGE(device_name, 0, 32) },
00451         { STR_RANGE(manufacturer, 0, 64) },
00452         { STR_RANGE(model_name, 0, 32) },
00453         { STR_RANGE(model_number, 0, 32) },
00454         { STR_RANGE(serial_number, 0, 32) },
00455         { STR(device_type) },
00456         { FUNC(os_version) },
00457         { STR(config_methods) },
00458         { INT_RANGE(wps_cred_processing, 0, 2) },
00459 #endif /* CONFIG_WPS */
00460         { FUNC(country) },
00461         { INT(bss_max_count) },
00462         { INT_RANGE(filter_ssids, 0, 1) }
00463 };
00464 
00465 #undef FUNC
00466 #undef _INT
00467 #undef INT
00468 #undef INT_RANGE
00469 #undef _STR
00470 #undef STR
00471 #undef STR_RANGE
00472 #define NUM_GLOBAL_FIELDS (sizeof(global_fields) / sizeof(global_fields[0]))
00473 
00474 
00475 static int wpa_config_process_global(struct wpa_config *config, char *pos,
00476                                      int line)
00477 {
00478         size_t i;
00479         int ret = 0;
00480 
00481         for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
00482                 const struct global_parse_data *field = &global_fields[i];
00483                 size_t flen = os_strlen(field->name);
00484                 if (os_strncmp(pos, field->name, flen) != 0 ||
00485                     pos[flen] != '=')
00486                         continue;
00487 
00488                 if (field->parser(field, config, line, pos + flen + 1)) {
00489                         wpa_printf(MSG_ERROR, "Line %d: failed to "
00490                                    "parse '%s'.", line, pos);
00491                         ret = -1;
00492                 }
00493                 break;
00494         }
00495         if (i == NUM_GLOBAL_FIELDS) {
00496                 wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
00497                            line, pos);
00498                 ret = -1;
00499         }
00500 
00501         return ret;
00502 }
00503 
00504 
00505 struct wpa_config * wpa_config_read(const char *name)
00506 {
00507         FILE *f;
00508         char buf[256], *pos;
00509         int errors = 0, line = 0;
00510         struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
00511         struct wpa_config *config;
00512         int id = 0;
00513 
00514         config = wpa_config_alloc_empty(NULL, NULL);
00515         if (config == NULL)
00516                 return NULL;
00517         wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name);
00518         f = fopen(name, "r");
00519         if (f == NULL) {
00520                 os_free(config);
00521                 return NULL;
00522         }
00523 
00524         while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
00525                 if (os_strcmp(pos, "network={") == 0) {
00526                         ssid = wpa_config_read_network(f, &line, id++);
00527                         if (ssid == NULL) {
00528                                 wpa_printf(MSG_ERROR, "Line %d: failed to "
00529                                            "parse network block.", line);
00530                                 errors++;
00531                                 continue;
00532                         }
00533                         if (head == NULL) {
00534                                 head = tail = ssid;
00535                         } else {
00536                                 tail->next = ssid;
00537                                 tail = ssid;
00538                         }
00539                         if (wpa_config_add_prio_network(config, ssid)) {
00540                                 wpa_printf(MSG_ERROR, "Line %d: failed to add "
00541                                            "network block to priority list.",
00542                                            line);
00543                                 errors++;
00544                                 continue;
00545                         }
00546 #ifndef CONFIG_NO_CONFIG_BLOBS
00547                 } else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
00548                         if (wpa_config_process_blob(config, f, &line, pos + 12)
00549                             < 0) {
00550                                 errors++;
00551                                 continue;
00552                         }
00553 #endif /* CONFIG_NO_CONFIG_BLOBS */
00554                 } else if (wpa_config_process_global(config, pos, line) < 0) {
00555                         wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
00556                                    "line '%s'.", line, pos);
00557                         errors++;
00558                         continue;
00559                 }
00560         }
00561 
00562         fclose(f);
00563 
00564         config->ssid = head;
00565         wpa_config_debug_dump_networks(config);
00566 
00567         if (errors) {
00568                 wpa_config_free(config);
00569                 config = NULL;
00570                 head = NULL;
00571         }
00572 
00573         return config;
00574 }
00575 
00576 
00577 #ifndef CONFIG_NO_CONFIG_WRITE
00578 
00579 static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
00580 {
00581         char *value = wpa_config_get(ssid, field);
00582         if (value == NULL)
00583                 return;
00584         fprintf(f, "\t%s=%s\n", field, value);
00585         os_free(value);
00586 }
00587 
00588 
00589 static void write_int(FILE *f, const char *field, int value, int def)
00590 {
00591         if (value == def)
00592                 return;
00593         fprintf(f, "\t%s=%d\n", field, value);
00594 }
00595 
00596 
00597 static void write_bssid(FILE *f, struct wpa_ssid *ssid)
00598 {
00599         char *value = wpa_config_get(ssid, "bssid");
00600         if (value == NULL)
00601                 return;
00602         fprintf(f, "\tbssid=%s\n", value);
00603         os_free(value);
00604 }
00605 
00606 
00607 static void write_psk(FILE *f, struct wpa_ssid *ssid)
00608 {
00609         char *value = wpa_config_get(ssid, "psk");
00610         if (value == NULL)
00611                 return;
00612         fprintf(f, "\tpsk=%s\n", value);
00613         os_free(value);
00614 }
00615 
00616 
00617 static void write_proto(FILE *f, struct wpa_ssid *ssid)
00618 {
00619         char *value;
00620 
00621         if (ssid->proto == DEFAULT_PROTO)
00622                 return;
00623 
00624         value = wpa_config_get(ssid, "proto");
00625         if (value == NULL)
00626                 return;
00627         if (value[0])
00628                 fprintf(f, "\tproto=%s\n", value);
00629         os_free(value);
00630 }
00631 
00632 
00633 static void write_key_mgmt(FILE *f, struct wpa_ssid *ssid)
00634 {
00635         char *value;
00636 
00637         if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
00638                 return;
00639 
00640         value = wpa_config_get(ssid, "key_mgmt");
00641         if (value == NULL)
00642                 return;
00643         if (value[0])
00644                 fprintf(f, "\tkey_mgmt=%s\n", value);
00645         os_free(value);
00646 }
00647 
00648 
00649 static void write_pairwise(FILE *f, struct wpa_ssid *ssid)
00650 {
00651         char *value;
00652 
00653         if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
00654                 return;
00655 
00656         value = wpa_config_get(ssid, "pairwise");
00657         if (value == NULL)
00658                 return;
00659         if (value[0])
00660                 fprintf(f, "\tpairwise=%s\n", value);
00661         os_free(value);
00662 }
00663 
00664 
00665 static void write_group(FILE *f, struct wpa_ssid *ssid)
00666 {
00667         char *value;
00668 
00669         if (ssid->group_cipher == DEFAULT_GROUP)
00670                 return;
00671 
00672         value = wpa_config_get(ssid, "group");
00673         if (value == NULL)
00674                 return;
00675         if (value[0])
00676                 fprintf(f, "\tgroup=%s\n", value);
00677         os_free(value);
00678 }
00679 
00680 
00681 static void write_auth_alg(FILE *f, struct wpa_ssid *ssid)
00682 {
00683         char *value;
00684 
00685         if (ssid->auth_alg == 0)
00686                 return;
00687 
00688         value = wpa_config_get(ssid, "auth_alg");
00689         if (value == NULL)
00690                 return;
00691         if (value[0])
00692                 fprintf(f, "\tauth_alg=%s\n", value);
00693         os_free(value);
00694 }
00695 
00696 
00697 #ifdef IEEE8021X_EAPOL
00698 static void write_eap(FILE *f, struct wpa_ssid *ssid)
00699 {
00700         char *value;
00701 
00702         value = wpa_config_get(ssid, "eap");
00703         if (value == NULL)
00704                 return;
00705 
00706         if (value[0])
00707                 fprintf(f, "\teap=%s\n", value);
00708         os_free(value);
00709 }
00710 #endif /* IEEE8021X_EAPOL */
00711 
00712 
00713 static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
00714 {
00715         char field[20], *value;
00716         int res;
00717 
00718         res = os_snprintf(field, sizeof(field), "wep_key%d", idx);
00719         if (res < 0 || (size_t) res >= sizeof(field))
00720                 return;
00721         value = wpa_config_get(ssid, field);
00722         if (value) {
00723                 fprintf(f, "\t%s=%s\n", field, value);
00724                 os_free(value);
00725         }
00726 }
00727 
00728 
00729 static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
00730 {
00731         int i;
00732 
00733 #define STR(t) write_str(f, #t, ssid)
00734 #define INT(t) write_int(f, #t, ssid->t, 0)
00735 #define INTe(t) write_int(f, #t, ssid->eap.t, 0)
00736 #define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
00737 #define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def)
00738 
00739         STR(ssid);
00740         INT(scan_ssid);
00741         write_bssid(f, ssid);
00742         write_psk(f, ssid);
00743         write_proto(f, ssid);
00744         write_key_mgmt(f, ssid);
00745         write_pairwise(f, ssid);
00746         write_group(f, ssid);
00747         write_auth_alg(f, ssid);
00748 #ifdef IEEE8021X_EAPOL
00749         write_eap(f, ssid);
00750         STR(identity);
00751         STR(anonymous_identity);
00752         STR(password);
00753         STR(ca_cert);
00754         STR(ca_path);
00755         STR(client_cert);
00756         STR(private_key);
00757         STR(private_key_passwd);
00758         STR(dh_file);
00759         STR(subject_match);
00760         STR(altsubject_match);
00761         STR(ca_cert2);
00762         STR(ca_path2);
00763         STR(client_cert2);
00764         STR(private_key2);
00765         STR(private_key2_passwd);
00766         STR(dh_file2);
00767         STR(subject_match2);
00768         STR(altsubject_match2);
00769         STR(phase1);
00770         STR(phase2);
00771         STR(pcsc);
00772         STR(pin);
00773         STR(engine_id);
00774         STR(key_id);
00775         STR(cert_id);
00776         STR(ca_cert_id);
00777         STR(key2_id);
00778         STR(pin2);
00779         STR(engine2_id);
00780         STR(cert2_id);
00781         STR(ca_cert2_id);
00782         INTe(engine);
00783         INTe(engine2);
00784         INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
00785 #endif /* IEEE8021X_EAPOL */
00786         for (i = 0; i < 4; i++)
00787                 write_wep_key(f, i, ssid);
00788         INT(wep_tx_keyidx);
00789         INT(priority);
00790 #ifdef IEEE8021X_EAPOL
00791         INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
00792         STR(pac_file);
00793         INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
00794 #endif /* IEEE8021X_EAPOL */
00795         INT(mode);
00796         INT(proactive_key_caching);
00797         INT(disabled);
00798         INT(peerkey);
00799 #ifdef CONFIG_IEEE80211W
00800         INT(ieee80211w);
00801 #endif /* CONFIG_IEEE80211W */
00802         STR(id_str);
00803 
00804 #undef STR
00805 #undef INT
00806 #undef INT_DEF
00807 }
00808 
00809 
00810 #ifndef CONFIG_NO_CONFIG_BLOBS
00811 static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob)
00812 {
00813         unsigned char *encoded;
00814 
00815         encoded = base64_encode(blob->data, blob->len, NULL);
00816         if (encoded == NULL)
00817                 return -1;
00818 
00819         fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded);
00820         os_free(encoded);
00821         return 0;
00822 }
00823 #endif /* CONFIG_NO_CONFIG_BLOBS */
00824 
00825 
00826 static void wpa_config_write_global(FILE *f, struct wpa_config *config)
00827 {
00828 #ifdef CONFIG_CTRL_IFACE
00829         if (config->ctrl_interface)
00830                 fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface);
00831         if (config->ctrl_interface_group)
00832                 fprintf(f, "ctrl_interface_group=%s\n",
00833                         config->ctrl_interface_group);
00834 #endif /* CONFIG_CTRL_IFACE */
00835         if (config->eapol_version != DEFAULT_EAPOL_VERSION)
00836                 fprintf(f, "eapol_version=%d\n", config->eapol_version);
00837         if (config->ap_scan != DEFAULT_AP_SCAN)
00838                 fprintf(f, "ap_scan=%d\n", config->ap_scan);
00839         if (config->fast_reauth != DEFAULT_FAST_REAUTH)
00840                 fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
00841         if (config->opensc_engine_path)
00842                 fprintf(f, "opensc_engine_path=%s\n",
00843                         config->opensc_engine_path);
00844         if (config->pkcs11_engine_path)
00845                 fprintf(f, "pkcs11_engine_path=%s\n",
00846                         config->pkcs11_engine_path);
00847         if (config->pkcs11_module_path)
00848                 fprintf(f, "pkcs11_module_path=%s\n",
00849                         config->pkcs11_module_path);
00850         if (config->driver_param)
00851                 fprintf(f, "driver_param=%s\n", config->driver_param);
00852         if (config->dot11RSNAConfigPMKLifetime)
00853                 fprintf(f, "dot11RSNAConfigPMKLifetime=%d\n",
00854                         config->dot11RSNAConfigPMKLifetime);
00855         if (config->dot11RSNAConfigPMKReauthThreshold)
00856                 fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%d\n",
00857                         config->dot11RSNAConfigPMKReauthThreshold);
00858         if (config->dot11RSNAConfigSATimeout)
00859                 fprintf(f, "dot11RSNAConfigSATimeout=%d\n",
00860                         config->dot11RSNAConfigSATimeout);
00861         if (config->update_config)
00862                 fprintf(f, "update_config=%d\n", config->update_config);
00863 #ifdef CONFIG_WPS
00864         if (!is_nil_uuid(config->uuid)) {
00865                 char buf[40];
00866                 uuid_bin2str(config->uuid, buf, sizeof(buf));
00867                 fprintf(f, "uuid=%s\n", buf);
00868         }
00869         if (config->device_name)
00870                 fprintf(f, "device_name=%s\n", config->device_name);
00871         if (config->manufacturer)
00872                 fprintf(f, "manufacturer=%s\n", config->manufacturer);
00873         if (config->model_name)
00874                 fprintf(f, "model_name=%s\n", config->model_name);
00875         if (config->model_number)
00876                 fprintf(f, "model_number=%s\n", config->model_number);
00877         if (config->serial_number)
00878                 fprintf(f, "serial_number=%s\n", config->serial_number);
00879         if (config->device_type)
00880                 fprintf(f, "device_type=%s\n", config->device_type);
00881         if (WPA_GET_BE32(config->os_version))
00882                 fprintf(f, "os_version=%08x\n",
00883                         WPA_GET_BE32(config->os_version));
00884         if (config->config_methods)
00885                 fprintf(f, "config_methods=%s\n", config->config_methods);
00886         if (config->wps_cred_processing)
00887                 fprintf(f, "wps_cred_processing=%d\n",
00888                         config->wps_cred_processing);
00889 #endif /* CONFIG_WPS */
00890         if (config->country[0] && config->country[1]) {
00891                 fprintf(f, "country=%c%c\n",
00892                         config->country[0], config->country[1]);
00893         }
00894         if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
00895                 fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
00896         if (config->filter_ssids)
00897                 fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
00898 }
00899 
00900 #endif /* CONFIG_NO_CONFIG_WRITE */
00901 
00902 
00903 int wpa_config_write(const char *name, struct wpa_config *config)
00904 {
00905 #ifndef CONFIG_NO_CONFIG_WRITE
00906         FILE *f;
00907         struct wpa_ssid *ssid;
00908 #ifndef CONFIG_NO_CONFIG_BLOBS
00909         struct wpa_config_blob *blob;
00910 #endif /* CONFIG_NO_CONFIG_BLOBS */
00911         int ret = 0;
00912 
00913         wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
00914 
00915         f = fopen(name, "w");
00916         if (f == NULL) {
00917                 wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name);
00918                 return -1;
00919         }
00920 
00921         wpa_config_write_global(f, config);
00922 
00923         for (ssid = config->ssid; ssid; ssid = ssid->next) {
00924                 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
00925                         continue; /* do not save temporary WPS networks */
00926                 fprintf(f, "\nnetwork={\n");
00927                 wpa_config_write_network(f, ssid);
00928                 fprintf(f, "}\n");
00929         }
00930 
00931 #ifndef CONFIG_NO_CONFIG_BLOBS
00932         for (blob = config->blobs; blob; blob = blob->next) {
00933                 ret = wpa_config_write_blob(f, blob);
00934                 if (ret)
00935                         break;
00936         }
00937 #endif /* CONFIG_NO_CONFIG_BLOBS */
00938 
00939         fclose(f);
00940 
00941         wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
00942                    name, ret ? "un" : "");
00943         return ret;
00944 #else /* CONFIG_NO_CONFIG_WRITE */
00945         return -1;
00946 #endif /* CONFIG_NO_CONFIG_WRITE */
00947 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:33