LCOV - code coverage report
Current view: top level - src/wps - wps_dev_attr.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 183 212 86.3 %
Date: 2014-03-02 Functions: 23 23 100.0 %
Branches: 56 82 68.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Wi-Fi Protected Setup - device attributes
       3                 :            :  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "includes.h"
      10                 :            : 
      11                 :            : #include "common.h"
      12                 :            : #include "wps_i.h"
      13                 :            : #include "wps_dev_attr.h"
      14                 :            : 
      15                 :            : 
      16                 :       2174 : int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg)
      17                 :            : {
      18                 :            :         size_t len;
      19                 :       2174 :         wpa_printf(MSG_DEBUG, "WPS:  * Manufacturer");
      20                 :       2174 :         wpabuf_put_be16(msg, ATTR_MANUFACTURER);
      21         [ +  + ]:       2174 :         len = dev->manufacturer ? os_strlen(dev->manufacturer) : 0;
      22                 :            : #ifndef CONFIG_WPS_STRICT
      23         [ +  + ]:       2174 :         if (len == 0) {
      24                 :            :                 /*
      25                 :            :                  * Some deployed WPS implementations fail to parse zero-length
      26                 :            :                  * attributes. As a workaround, send a space character if the
      27                 :            :                  * device attribute string is empty.
      28                 :            :                  */
      29                 :       2091 :                 wpabuf_put_be16(msg, 1);
      30                 :       2091 :                 wpabuf_put_u8(msg, ' ');
      31                 :       2091 :                 return 0;
      32                 :            :         }
      33                 :            : #endif /* CONFIG_WPS_STRICT */
      34                 :         83 :         wpabuf_put_be16(msg, len);
      35                 :         83 :         wpabuf_put_data(msg, dev->manufacturer, len);
      36                 :       2174 :         return 0;
      37                 :            : }
      38                 :            : 
      39                 :            : 
      40                 :       2174 : int wps_build_model_name(struct wps_device_data *dev, struct wpabuf *msg)
      41                 :            : {
      42                 :            :         size_t len;
      43                 :       2174 :         wpa_printf(MSG_DEBUG, "WPS:  * Model Name");
      44                 :       2174 :         wpabuf_put_be16(msg, ATTR_MODEL_NAME);
      45         [ +  + ]:       2174 :         len = dev->model_name ? os_strlen(dev->model_name) : 0;
      46                 :            : #ifndef CONFIG_WPS_STRICT
      47         [ +  + ]:       2174 :         if (len == 0) {
      48                 :            :                 /*
      49                 :            :                  * Some deployed WPS implementations fail to parse zero-length
      50                 :            :                  * attributes. As a workaround, send a space character if the
      51                 :            :                  * device attribute string is empty.
      52                 :            :                  */
      53                 :       2091 :                 wpabuf_put_be16(msg, 1);
      54                 :       2091 :                 wpabuf_put_u8(msg, ' ');
      55                 :       2091 :                 return 0;
      56                 :            :         }
      57                 :            : #endif /* CONFIG_WPS_STRICT */
      58                 :         83 :         wpabuf_put_be16(msg, len);
      59                 :         83 :         wpabuf_put_data(msg, dev->model_name, len);
      60                 :       2174 :         return 0;
      61                 :            : }
      62                 :            : 
      63                 :            : 
      64                 :       2174 : int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg)
      65                 :            : {
      66                 :            :         size_t len;
      67                 :       2174 :         wpa_printf(MSG_DEBUG, "WPS:  * Model Number");
      68                 :       2174 :         wpabuf_put_be16(msg, ATTR_MODEL_NUMBER);
      69         [ +  + ]:       2174 :         len = dev->model_number ? os_strlen(dev->model_number) : 0;
      70                 :            : #ifndef CONFIG_WPS_STRICT
      71         [ +  + ]:       2174 :         if (len == 0) {
      72                 :            :                 /*
      73                 :            :                  * Some deployed WPS implementations fail to parse zero-length
      74                 :            :                  * attributes. As a workaround, send a space character if the
      75                 :            :                  * device attribute string is empty.
      76                 :            :                  */
      77                 :       2091 :                 wpabuf_put_be16(msg, 1);
      78                 :       2091 :                 wpabuf_put_u8(msg, ' ');
      79                 :       2091 :                 return 0;
      80                 :            :         }
      81                 :            : #endif /* CONFIG_WPS_STRICT */
      82                 :         83 :         wpabuf_put_be16(msg, len);
      83                 :         83 :         wpabuf_put_data(msg, dev->model_number, len);
      84                 :       2174 :         return 0;
      85                 :            : }
      86                 :            : 
      87                 :            : 
      88                 :        819 : int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg)
      89                 :            : {
      90                 :            :         size_t len;
      91                 :        819 :         wpa_printf(MSG_DEBUG, "WPS:  * Serial Number");
      92                 :        819 :         wpabuf_put_be16(msg, ATTR_SERIAL_NUMBER);
      93         [ +  + ]:        819 :         len = dev->serial_number ? os_strlen(dev->serial_number) : 0;
      94                 :            : #ifndef CONFIG_WPS_STRICT
      95         [ +  + ]:        819 :         if (len == 0) {
      96                 :            :                 /*
      97                 :            :                  * Some deployed WPS implementations fail to parse zero-length
      98                 :            :                  * attributes. As a workaround, send a space character if the
      99                 :            :                  * device attribute string is empty.
     100                 :            :                  */
     101                 :        736 :                 wpabuf_put_be16(msg, 1);
     102                 :        736 :                 wpabuf_put_u8(msg, ' ');
     103                 :        736 :                 return 0;
     104                 :            :         }
     105                 :            : #endif /* CONFIG_WPS_STRICT */
     106                 :         83 :         wpabuf_put_be16(msg, len);
     107                 :         83 :         wpabuf_put_data(msg, dev->serial_number, len);
     108                 :        819 :         return 0;
     109                 :            : }
     110                 :            : 
     111                 :            : 
     112                 :       2477 : int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg)
     113                 :            : {
     114                 :       2477 :         wpa_printf(MSG_DEBUG, "WPS:  * Primary Device Type");
     115                 :       2477 :         wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE);
     116                 :       2477 :         wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
     117                 :       2477 :         wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN);
     118                 :       2477 :         return 0;
     119                 :            : }
     120                 :            : 
     121                 :            : 
     122                 :       1355 : int wps_build_secondary_dev_type(struct wps_device_data *dev,
     123                 :            :                                   struct wpabuf *msg)
     124                 :            : {
     125         [ +  + ]:       1355 :         if (!dev->num_sec_dev_types)
     126                 :       1311 :                 return 0;
     127                 :            : 
     128                 :         44 :         wpa_printf(MSG_DEBUG, "WPS:  * Secondary Device Type");
     129                 :         44 :         wpabuf_put_be16(msg, ATTR_SECONDARY_DEV_TYPE_LIST);
     130                 :         44 :         wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
     131                 :         44 :         wpabuf_put_data(msg, dev->sec_dev_type,
     132                 :         44 :                         WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
     133                 :            : 
     134                 :       1355 :         return 0;
     135                 :            : }
     136                 :            : 
     137                 :            : 
     138                 :       1355 : int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
     139                 :            :                            unsigned int num_req_dev_types,
     140                 :            :                            const u8 *req_dev_types)
     141                 :            : {
     142                 :            :         unsigned int i;
     143                 :            : 
     144         [ +  + ]:       1363 :         for (i = 0; i < num_req_dev_types; i++) {
     145                 :          8 :                 wpa_hexdump(MSG_DEBUG, "WPS: * Requested Device Type",
     146                 :          8 :                             req_dev_types + i * WPS_DEV_TYPE_LEN,
     147                 :            :                             WPS_DEV_TYPE_LEN);
     148                 :          8 :                 wpabuf_put_be16(msg, ATTR_REQUESTED_DEV_TYPE);
     149                 :          8 :                 wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
     150                 :          8 :                 wpabuf_put_data(msg, req_dev_types + i * WPS_DEV_TYPE_LEN,
     151                 :            :                                 WPS_DEV_TYPE_LEN);
     152                 :            :         }
     153                 :            : 
     154                 :       1355 :         return 0;
     155                 :            : }
     156                 :            : 
     157                 :            : 
     158                 :       2477 : int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg)
     159                 :            : {
     160                 :            :         size_t len;
     161                 :       2477 :         wpa_printf(MSG_DEBUG, "WPS:  * Device Name");
     162                 :       2477 :         wpabuf_put_be16(msg, ATTR_DEV_NAME);
     163         [ +  + ]:       2477 :         len = dev->device_name ? os_strlen(dev->device_name) : 0;
     164                 :            : #ifndef CONFIG_WPS_STRICT
     165         [ +  + ]:       2477 :         if (len == 0) {
     166                 :            :                 /*
     167                 :            :                  * Some deployed WPS implementations fail to parse zero-length
     168                 :            :                  * attributes. As a workaround, send a space character if the
     169                 :            :                  * device attribute string is empty.
     170                 :            :                  */
     171                 :        238 :                 wpabuf_put_be16(msg, 1);
     172                 :        238 :                 wpabuf_put_u8(msg, ' ');
     173                 :        238 :                 return 0;
     174                 :            :         }
     175                 :            : #endif /* CONFIG_WPS_STRICT */
     176                 :       2239 :         wpabuf_put_be16(msg, len);
     177                 :       2239 :         wpabuf_put_data(msg, dev->device_name, len);
     178                 :       2477 :         return 0;
     179                 :            : }
     180                 :            : 
     181                 :            : 
     182                 :        799 : int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg)
     183                 :            : {
     184   [ +  -  +  - ]:       1598 :         if (wps_build_manufacturer(dev, msg) ||
     185         [ +  - ]:       1598 :             wps_build_model_name(dev, msg) ||
     186         [ +  - ]:       1598 :             wps_build_model_number(dev, msg) ||
     187         [ +  - ]:       1598 :             wps_build_serial_number(dev, msg) ||
     188         [ -  + ]:       1598 :             wps_build_primary_dev_type(dev, msg) ||
     189                 :        799 :             wps_build_dev_name(dev, msg))
     190                 :          0 :                 return -1;
     191                 :        799 :         return 0;
     192                 :            : }
     193                 :            : 
     194                 :            : 
     195                 :        310 : int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg)
     196                 :            : {
     197                 :        310 :         wpa_printf(MSG_DEBUG, "WPS:  * OS Version");
     198                 :        310 :         wpabuf_put_be16(msg, ATTR_OS_VERSION);
     199                 :        310 :         wpabuf_put_be16(msg, 4);
     200                 :        310 :         wpabuf_put_be32(msg, 0x80000000 | dev->os_version);
     201                 :        310 :         return 0;
     202                 :            : }
     203                 :            : 
     204                 :            : 
     205                 :        156 : int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
     206                 :            : {
     207         [ +  + ]:        156 :         if (dev->vendor_ext_m1 != NULL) {
     208                 :         12 :                 wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension M1",
     209                 :          6 :                             wpabuf_head_u8(dev->vendor_ext_m1),
     210                 :          6 :                             wpabuf_len(dev->vendor_ext_m1));
     211                 :          6 :                 wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
     212                 :          6 :                 wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1));
     213                 :          6 :                 wpabuf_put_buf(msg, dev->vendor_ext_m1);
     214                 :            :         }
     215                 :        156 :         return 0;
     216                 :            : }
     217                 :            : 
     218                 :            : 
     219                 :       1707 : int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
     220                 :            :                        u8 rf_band)
     221                 :            : {
     222         [ +  + ]:       1707 :         return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
     223                 :            : }
     224                 :            : 
     225                 :            : 
     226                 :        978 : int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
     227                 :            : {
     228                 :            :         int i;
     229                 :            : 
     230         [ +  + ]:      10758 :         for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
     231         [ +  - ]:       9780 :                 if (dev->vendor_ext[i] == NULL)
     232                 :       9780 :                         continue;
     233                 :          0 :                 wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension",
     234                 :          0 :                             wpabuf_head_u8(dev->vendor_ext[i]),
     235                 :          0 :                             wpabuf_len(dev->vendor_ext[i]));
     236                 :          0 :                 wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
     237                 :          0 :                 wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext[i]));
     238                 :          0 :                 wpabuf_put_buf(msg, dev->vendor_ext[i]);
     239                 :            :         }
     240                 :            : 
     241                 :        978 :         return 0;
     242                 :            : }
     243                 :            : 
     244                 :            : 
     245                 :        287 : static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
     246                 :            :                                     size_t str_len)
     247                 :            : {
     248         [ -  + ]:        287 :         if (str == NULL) {
     249                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received");
     250                 :          0 :                 return -1;
     251                 :            :         }
     252                 :            : 
     253                 :        287 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
     254                 :            : 
     255                 :        287 :         os_free(dev->manufacturer);
     256                 :        287 :         dev->manufacturer = dup_binstr(str, str_len);
     257         [ -  + ]:        287 :         if (dev->manufacturer == NULL)
     258                 :          0 :                 return -1;
     259                 :            : 
     260                 :        287 :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :            : 
     264                 :        287 : static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
     265                 :            :                                   size_t str_len)
     266                 :            : {
     267         [ -  + ]:        287 :         if (str == NULL) {
     268                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Model Name received");
     269                 :          0 :                 return -1;
     270                 :            :         }
     271                 :            : 
     272                 :        287 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
     273                 :            : 
     274                 :        287 :         os_free(dev->model_name);
     275                 :        287 :         dev->model_name = dup_binstr(str, str_len);
     276         [ -  + ]:        287 :         if (dev->model_name == NULL)
     277                 :          0 :                 return -1;
     278                 :            : 
     279                 :        287 :         return 0;
     280                 :            : }
     281                 :            : 
     282                 :            : 
     283                 :        287 : static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
     284                 :            :                                     size_t str_len)
     285                 :            : {
     286         [ -  + ]:        287 :         if (str == NULL) {
     287                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Model Number received");
     288                 :          0 :                 return -1;
     289                 :            :         }
     290                 :            : 
     291                 :        287 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
     292                 :            : 
     293                 :        287 :         os_free(dev->model_number);
     294                 :        287 :         dev->model_number = dup_binstr(str, str_len);
     295         [ -  + ]:        287 :         if (dev->model_number == NULL)
     296                 :          0 :                 return -1;
     297                 :            : 
     298                 :        287 :         return 0;
     299                 :            : }
     300                 :            : 
     301                 :            : 
     302                 :        287 : static int wps_process_serial_number(struct wps_device_data *dev,
     303                 :            :                                      const u8 *str, size_t str_len)
     304                 :            : {
     305         [ -  + ]:        287 :         if (str == NULL) {
     306                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Serial Number received");
     307                 :          0 :                 return -1;
     308                 :            :         }
     309                 :            : 
     310                 :        287 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
     311                 :            : 
     312                 :        287 :         os_free(dev->serial_number);
     313                 :        287 :         dev->serial_number = dup_binstr(str, str_len);
     314         [ -  + ]:        287 :         if (dev->serial_number == NULL)
     315                 :          0 :                 return -1;
     316                 :            : 
     317                 :        287 :         return 0;
     318                 :            : }
     319                 :            : 
     320                 :            : 
     321                 :        287 : static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
     322                 :            :                                 size_t str_len)
     323                 :            : {
     324         [ -  + ]:        287 :         if (str == NULL) {
     325                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Device Name received");
     326                 :          0 :                 return -1;
     327                 :            :         }
     328                 :            : 
     329                 :        287 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
     330                 :            : 
     331                 :        287 :         os_free(dev->device_name);
     332                 :        287 :         dev->device_name = dup_binstr(str, str_len);
     333         [ -  + ]:        287 :         if (dev->device_name == NULL)
     334                 :          0 :                 return -1;
     335                 :            : 
     336                 :        287 :         return 0;
     337                 :            : }
     338                 :            : 
     339                 :            : 
     340                 :        287 : static int wps_process_primary_dev_type(struct wps_device_data *dev,
     341                 :            :                                         const u8 *dev_type)
     342                 :            : {
     343                 :            : #ifndef CONFIG_NO_STDOUT_DEBUG
     344                 :            :         char devtype[WPS_DEV_TYPE_BUFSIZE];
     345                 :            : #endif /* CONFIG_NO_STDOUT_DEBUG */
     346                 :            : 
     347         [ -  + ]:        287 :         if (dev_type == NULL) {
     348                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
     349                 :          0 :                 return -1;
     350                 :            :         }
     351                 :            : 
     352                 :        287 :         os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
     353                 :        287 :         wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
     354                 :        287 :                    wps_dev_type_bin2str(dev->pri_dev_type, devtype,
     355                 :            :                                         sizeof(devtype)));
     356                 :            : 
     357                 :        287 :         return 0;
     358                 :            : }
     359                 :            : 
     360                 :            : 
     361                 :        287 : int wps_process_device_attrs(struct wps_device_data *dev,
     362                 :            :                              struct wps_parse_attr *attr)
     363                 :            : {
     364         [ +  - ]:        287 :         if (wps_process_manufacturer(dev, attr->manufacturer,
     365         [ +  - ]:        287 :                                      attr->manufacturer_len) ||
     366                 :        287 :             wps_process_model_name(dev, attr->model_name,
     367         [ +  - ]:        287 :                                    attr->model_name_len) ||
     368                 :        287 :             wps_process_model_number(dev, attr->model_number,
     369         [ +  - ]:        287 :                                      attr->model_number_len) ||
     370                 :        287 :             wps_process_serial_number(dev, attr->serial_number,
     371         [ +  - ]:        287 :                                       attr->serial_number_len) ||
     372         [ -  + ]:        574 :             wps_process_primary_dev_type(dev, attr->primary_dev_type) ||
     373                 :        287 :             wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len))
     374                 :          0 :                 return -1;
     375                 :        287 :         return 0;
     376                 :            : }
     377                 :            : 
     378                 :            : 
     379                 :        154 : int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
     380                 :            : {
     381         [ -  + ]:        154 :         if (ver == NULL) {
     382                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No OS Version received");
     383                 :          0 :                 return -1;
     384                 :            :         }
     385                 :            : 
     386                 :        154 :         dev->os_version = WPA_GET_BE32(ver);
     387                 :        154 :         wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version);
     388                 :            : 
     389                 :        154 :         return 0;
     390                 :            : }
     391                 :            : 
     392                 :            : 
     393                 :        154 : int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
     394                 :            : {
     395         [ -  + ]:        154 :         if (bands == NULL) {
     396                 :          0 :                 wpa_printf(MSG_DEBUG, "WPS: No RF Bands received");
     397                 :          0 :                 return -1;
     398                 :            :         }
     399                 :            : 
     400                 :        154 :         dev->rf_bands = *bands;
     401                 :        154 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands);
     402                 :            : 
     403                 :        154 :         return 0;
     404                 :            : }
     405                 :            : 
     406                 :            : 
     407                 :        571 : void wps_device_data_free(struct wps_device_data *dev)
     408                 :            : {
     409                 :        571 :         os_free(dev->device_name);
     410                 :        571 :         dev->device_name = NULL;
     411                 :        571 :         os_free(dev->manufacturer);
     412                 :        571 :         dev->manufacturer = NULL;
     413                 :        571 :         os_free(dev->model_name);
     414                 :        571 :         dev->model_name = NULL;
     415                 :        571 :         os_free(dev->model_number);
     416                 :        571 :         dev->model_number = NULL;
     417                 :        571 :         os_free(dev->serial_number);
     418                 :        571 :         dev->serial_number = NULL;
     419                 :        571 : }

Generated by: LCOV version 1.9