~elementary-os/ubuntu-package-imports/ubiquity-bionic

« back to all changes in this revision

Viewing changes to d-i/source/netcfg/wireless.c

  • Committer: RabbitBot
  • Date: 2018-02-05 14:44:42 UTC
  • Revision ID: rabbitbot@elementary.io-20180205144442-vt0fvth7zus90wjh
Initial import, version 17.10.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Wireless support using iwlib for netcfg.
 
2
 * (C) 2004 Joshua Kwan, Bastian Blank
 
3
 *
 
4
 * Licensed under the GNU General Public License
 
5
 */
 
6
 
 
7
#include "netcfg.h"
 
8
 
 
9
#ifdef WIRELESS
 
10
#include <debian-installer/log.h>
 
11
#include <iwlib.h>
 
12
#include <sys/types.h>
 
13
#include <assert.h>
 
14
 
 
15
#define ENTER_MANUALLY 10
 
16
 
 
17
 
 
18
int is_wireless_iface (const char* if_name)
 
19
{
 
20
    wireless_config wc;
 
21
    return (iw_get_basic_config (wfd, (char*)if_name, &wc) == 0);
 
22
}
 
23
 
 
24
void free_network_list(wireless_scan **network_list)
 
25
{
 
26
    wireless_scan *old, *network;
 
27
 
 
28
    if (network_list == NULL) {
 
29
        return;
 
30
    }
 
31
 
 
32
    for (network = *network_list; network; ) {
 
33
        old = network;
 
34
        network = network->next;
 
35
        free(old);
 
36
    }
 
37
 
 
38
    *network_list = NULL;
 
39
}
 
40
 
 
41
int netcfg_wireless_choose_essid_manually(struct debconfclient *client,
 
42
        struct netcfg_interface *interface, char *question)
 
43
{
 
44
    wireless_config wconf;
 
45
 
 
46
    iw_get_basic_config (wfd, interface->name, &wconf);
 
47
 
 
48
    debconf_subst(client, question, "iface", interface->name);
 
49
    debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", interface->name);
 
50
 
 
51
    if (debconf_go(client) == CMD_GOBACK) {
 
52
        debconf_fset(client, question, "seen", "false");
 
53
        return GO_BACK;
 
54
    }
 
55
 
 
56
    debconf_get(client, "netcfg/wireless_adhoc_managed");
 
57
 
 
58
    if (!strcmp(client->value, "Ad-hoc network (Peer to peer)")) {
 
59
        interface->mode = ADHOC;
 
60
    }
 
61
 
 
62
    wconf.has_mode = 1;
 
63
    wconf.mode = interface->mode;
 
64
 
 
65
get_essid:
 
66
    debconf_input(client, "high", question);
 
67
 
 
68
    if (debconf_go(client) == CMD_GOBACK) {
 
69
        return GO_BACK;
 
70
    }
 
71
 
 
72
    debconf_get(client, question);
 
73
 
 
74
    if (client->value && strlen(client->value) > IW_ESSID_MAX_SIZE) {
 
75
        char max_len_string[5];
 
76
        sprintf(max_len_string, "%d", IW_ESSID_MAX_SIZE);
 
77
        debconf_capb(client, "");
 
78
        debconf_subst(client, "netcfg/invalid_essid", "essid", client->value);
 
79
        debconf_subst(client, "netcfg/invalid_essid", "max_essid_len",
 
80
                max_len_string);
 
81
        debconf_input(client, "critical", "netcfg/invalid_essid");
 
82
        debconf_go(client);
 
83
 
 
84
        debconf_fset(client, question, "seen", "false");
 
85
        debconf_capb(client, "backup");
 
86
        goto get_essid;
 
87
    }
 
88
 
 
89
    interface->essid = strdup(client->value);
 
90
 
 
91
    memset(wconf.essid, 0, IW_ESSID_MAX_SIZE + 1);
 
92
    snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", interface->essid);
 
93
    wconf.has_essid = 1;
 
94
    wconf.essid_on = 1;
 
95
 
 
96
    iw_set_basic_config(wfd, interface->name, &wconf);
 
97
 
 
98
    di_info("Network chosen: %s. Proceeding to connect.", interface->essid);
 
99
 
 
100
    return 0;
 
101
}
 
102
 
 
103
int exists_in_network_list(wireless_scan_head list, wireless_scan *network)
 
104
{
 
105
    wireless_scan *it;
 
106
 
 
107
    for (it = list.result; it != network; it = it->next) {
 
108
        if (strcmp(it->b.essid, network->b.essid) == 0) {
 
109
            return 1;
 
110
        }
 
111
    }
 
112
 
 
113
    return 0;
 
114
}
 
115
 
 
116
int netcfg_wireless_show_essids(struct debconfclient *client, struct netcfg_interface *interface)
 
117
{
 
118
    wireless_scan_head network_list;
 
119
    wireless_config wconf;
 
120
    char *buffer;
 
121
    int essid_list_len = 1;
 
122
 
 
123
    iw_get_basic_config (wfd, interface->name, &wconf);
 
124
    netcfg_interface_up(interface);
 
125
 
 
126
    if (iw_scan(wfd, interface->name, iw_get_kernel_we_version(),
 
127
                &network_list) >= 0 ) {
 
128
        wireless_scan *network;
 
129
 
 
130
        di_info("Scan of wireless interface %s succeeded.", interface->name);
 
131
 
 
132
        /* Determine the actual length of the buffer. */
 
133
        for (network = network_list.result; network; network =
 
134
            network->next) {
 
135
            if (!exists_in_network_list(network_list, network)) {
 
136
                essid_list_len += (strlen(network->b.essid) + 2);
 
137
            }
 
138
        }
 
139
        /* Buffer initialization. */
 
140
        buffer = malloc(essid_list_len * sizeof(char));
 
141
        if (buffer == NULL) {
 
142
            /* Error in memory allocation. */
 
143
            di_warning("Unable to allocate memory for network list buffer.");
 
144
            return ENTER_MANUALLY;
 
145
        }
 
146
        strcpy(buffer, "");
 
147
 
 
148
        /* Create list of available ESSIDs. */
 
149
        for (network = network_list.result; network; network = network->next) {
 
150
            if (!exists_in_network_list(network_list, network)) {
 
151
                strcat(buffer, network->b.essid);
 
152
                strcat(buffer, ", ");
 
153
            }
 
154
        }
 
155
 
 
156
        /* Asking the user. */
 
157
        debconf_capb(client, "backup");
 
158
        debconf_subst(client, "netcfg/wireless_show_essids", "essid_list", buffer);
 
159
        debconf_fset(client, "netcfg/wireless_show_essids", "seen", "false");
 
160
        debconf_input(client, "high", "netcfg/wireless_show_essids");
 
161
 
 
162
        if (debconf_go(client) == CMD_GOBACK) {
 
163
            debconf_fset(client, "netcfg/wireless_show_essids", "seen",
 
164
                    "false");
 
165
            free_network_list(&network_list.result);
 
166
            free(buffer);
 
167
 
 
168
            return GO_BACK;
 
169
        }
 
170
 
 
171
        debconf_get(client, "netcfg/wireless_show_essids");
 
172
 
 
173
        /* User wants to enter an ESSID manually. */
 
174
        if (strcmp(client->value, "manual") == 0) {
 
175
            free_network_list(&network_list.result);
 
176
            free(buffer);
 
177
 
 
178
            return ENTER_MANUALLY;
 
179
        }
 
180
 
 
181
        /* User has chosen a network from the list, need to find which one and
 
182
         * get its cofiguration. */
 
183
        for (network = network_list.result; network; network = network->next) {
 
184
            if (strcmp(network->b.essid, client->value) == 0) {
 
185
                wconf = network->b;
 
186
                interface->essid = strdup(network->b.essid);
 
187
                break;
 
188
            }
 
189
        }
 
190
 
 
191
        /* Free the network list. */
 
192
        free_network_list(&network_list.result);
 
193
        free(buffer);
 
194
    }
 
195
    else {
 
196
        /* Go directly to choosing manually, use the wireless_essid_again
 
197
         * question. */
 
198
        if (netcfg_wireless_choose_essid_manually(client, interface,
 
199
                "netcfg/wireless_essid_again") == GO_BACK) {
 
200
 
 
201
            return GO_BACK;
 
202
        }
 
203
 
 
204
        return 0;
 
205
    }
 
206
 
 
207
    iw_set_basic_config(wfd, interface->name, &wconf);
 
208
    netcfg_interface_down(interface);
 
209
 
 
210
    di_info("Network chosen: %s. Proceeding to connect.", interface->essid);
 
211
 
 
212
    return 0;
 
213
}
 
214
 
 
215
int netcfg_wireless_set_essid(struct debconfclient *client, struct netcfg_interface *interface)
 
216
{
 
217
    wireless_config wconf;
 
218
    int choose_ret;
 
219
 
 
220
select_essid:
 
221
    iw_get_basic_config(wfd, interface->name, &wconf);
 
222
 
 
223
    choose_ret = netcfg_wireless_show_essids(client, interface);
 
224
 
 
225
    if (choose_ret == GO_BACK) {
 
226
        return GO_BACK;
 
227
    }
 
228
 
 
229
    if (choose_ret == ENTER_MANUALLY) {
 
230
        if (netcfg_wireless_choose_essid_manually(client, interface,
 
231
                                      "netcfg/wireless_essid") == GO_BACK) {
 
232
            goto select_essid;
 
233
        }
 
234
    }
 
235
 
 
236
    return 0;
 
237
}
 
238
 
 
239
static void unset_wep_key (const char *if_name)
 
240
{
 
241
    wireless_config wconf;
 
242
 
 
243
    iw_get_basic_config(wfd, if_name, &wconf);
 
244
 
 
245
    wconf.has_key = 1;
 
246
    wconf.key[0] = '\0';
 
247
    wconf.key_flags = IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
 
248
    wconf.key_size = 0;
 
249
 
 
250
    iw_set_basic_config (wfd, if_name, &wconf);
 
251
}
 
252
 
 
253
int netcfg_wireless_set_wep (struct debconfclient * client, struct netcfg_interface *interface)
 
254
{
 
255
    wireless_config wconf;
 
256
    char* rv = NULL;
 
257
    int ret, keylen, err = 0;
 
258
    unsigned char buf [IW_ENCODING_TOKEN_MAX + 1];
 
259
    struct iwreq wrq;
 
260
 
 
261
    iw_get_basic_config (wfd, interface->name, &wconf);
 
262
 
 
263
    debconf_subst(client, "netcfg/wireless_wep", "iface", interface->name);
 
264
    debconf_input (client, "high", "netcfg/wireless_wep");
 
265
    ret = debconf_go(client);
 
266
 
 
267
    if (ret == CMD_GOBACK)
 
268
        return GO_BACK;
 
269
 
 
270
    debconf_get(client, "netcfg/wireless_wep");
 
271
    rv = client->value;
 
272
 
 
273
    if (empty_str(rv)) {
 
274
        unset_wep_key (interface->name);
 
275
 
 
276
        if (interface->wepkey != NULL) {
 
277
            free(interface->wepkey);
 
278
            interface->wepkey = NULL;
 
279
        }
 
280
 
 
281
        return 0;
 
282
    }
 
283
 
 
284
    while ((keylen = iw_in_key (rv, buf)) == -1) {
 
285
        debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
 
286
        debconf_input(client, "critical", "netcfg/invalid_wep");
 
287
        debconf_go(client);
 
288
 
 
289
        debconf_input (client, "high", "netcfg/wireless_wep");
 
290
        ret = debconf_go(client);
 
291
 
 
292
        if (ret == CMD_GOBACK)
 
293
            return GO_BACK;
 
294
 
 
295
        debconf_get(client, "netcfg/wireless_wep");
 
296
        rv = client->value;
 
297
    }
 
298
 
 
299
    /* Now rv is safe to store since it parsed fine */
 
300
    interface->wepkey = strdup(rv);
 
301
 
 
302
    wrq.u.data.pointer = buf;
 
303
    wrq.u.data.flags = 0;
 
304
    wrq.u.data.length = keylen;
 
305
 
 
306
    if ((err = iw_set_ext(skfd, interface->name, SIOCSIWENCODE, &wrq)) < 0) {
 
307
        di_warning("setting WEP key on %s failed with code %d", interface->name, err);
 
308
        return -1;
 
309
    }
 
310
 
 
311
    return 0;
 
312
}
 
313
 
 
314
#else
 
315
 
 
316
int is_wireless_iface (const char *if_name)
 
317
{
 
318
    (void) if_name;
 
319
    return 0;
 
320
}
 
321
 
 
322
int netcfg_wireless_set_essid (struct debconfclient *client, struct netcfg_interface *interface)
 
323
{
 
324
    (void) client;
 
325
    (void) interface;
 
326
    return 0;
 
327
}
 
328
 
 
329
int netcfg_wireless_set_wep (struct debconfclient *client, struct netcfg_interface *interface)
 
330
{
 
331
    (void) client;
 
332
    (void) interface;
 
333
    return 0;
 
334
}
 
335
 
 
336
#endif