~elementary-os/ubuntu-package-imports/network-manager-applet-xenial

« back to all changes in this revision

Viewing changes to src/utils/utils.c

  • Committer: RabbitBot
  • Date: 2016-01-13 11:35:12 UTC
  • Revision ID: rabbitbot@elementary.io-20160113113512-k3ejh0yxzvm2l7n0
Initial import, version 1.0.10-1ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
2
/* NetworkManager Applet -- allow user control over networking
 
3
 *
 
4
 * Dan Williams <dcbw@redhat.com>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License along
 
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
19
 *
 
20
 * Copyright 2007 - 2015 Red Hat, Inc.
 
21
 */
 
22
 
 
23
#include <config.h>
 
24
#include <string.h>
 
25
#include <netinet/ether.h>
 
26
#include <glib.h>
 
27
#include <glib/gi18n.h>
 
28
#include <gtk/gtk.h>
 
29
 
 
30
#include <nm-setting-connection.h>
 
31
#include <nm-utils.h>
 
32
 
 
33
#include "utils.h"
 
34
 
 
35
/*
 
36
 * utils_ether_addr_valid
 
37
 *
 
38
 * Compares an Ethernet address against known invalid addresses.
 
39
 *
 
40
 */
 
41
gboolean
 
42
utils_ether_addr_valid (const struct ether_addr *test_addr)
 
43
{
 
44
        guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
45
        guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
46
        guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
 
47
        guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
 
48
 
 
49
        g_return_val_if_fail (test_addr != NULL, FALSE);
 
50
 
 
51
        /* Compare the AP address the card has with invalid ethernet MAC addresses. */
 
52
        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN))
 
53
                return FALSE;
 
54
 
 
55
        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN))
 
56
                return FALSE;
 
57
 
 
58
        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN))
 
59
                return FALSE;
 
60
 
 
61
        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN))
 
62
                return FALSE;
 
63
 
 
64
        if (test_addr->ether_addr_octet[0] & 1)                 /* Multicast addresses */
 
65
                return FALSE;
 
66
        
 
67
        return TRUE;
 
68
}
 
69
 
 
70
char *
 
71
utils_hash_ap (const GByteArray *ssid,
 
72
               NM80211Mode mode,
 
73
               guint32 flags,
 
74
               guint32 wpa_flags,
 
75
               guint32 rsn_flags)
 
76
{
 
77
        unsigned char input[66];
 
78
 
 
79
        memset (&input[0], 0, sizeof (input));
 
80
 
 
81
        if (ssid)
 
82
                memcpy (input, ssid->data, ssid->len);
 
83
 
 
84
        if (mode == NM_802_11_MODE_INFRA)
 
85
                input[32] |= (1 << 0);
 
86
        else if (mode == NM_802_11_MODE_ADHOC)
 
87
                input[32] |= (1 << 1);
 
88
        else
 
89
                input[32] |= (1 << 2);
 
90
 
 
91
        /* Separate out no encryption, WEP-only, and WPA-capable */
 
92
        if (  !(flags & NM_802_11_AP_FLAGS_PRIVACY)
 
93
            && (wpa_flags == NM_802_11_AP_SEC_NONE)
 
94
            && (rsn_flags == NM_802_11_AP_SEC_NONE))
 
95
                input[32] |= (1 << 3);
 
96
        else if (   (flags & NM_802_11_AP_FLAGS_PRIVACY)
 
97
                 && (wpa_flags == NM_802_11_AP_SEC_NONE)
 
98
                 && (rsn_flags == NM_802_11_AP_SEC_NONE))
 
99
                input[32] |= (1 << 4);
 
100
        else if (   !(flags & NM_802_11_AP_FLAGS_PRIVACY)
 
101
                 &&  (wpa_flags != NM_802_11_AP_SEC_NONE)
 
102
                 &&  (rsn_flags != NM_802_11_AP_SEC_NONE))
 
103
                input[32] |= (1 << 5);
 
104
        else
 
105
                input[32] |= (1 << 6);
 
106
 
 
107
        /* duplicate it */
 
108
        memcpy (&input[33], &input[0], 32);
 
109
        return g_compute_checksum_for_data (G_CHECKSUM_MD5, input, sizeof (input));
 
110
}
 
111
 
 
112
typedef struct {
 
113
        const char *tag;
 
114
        const char *replacement;
 
115
} Tag;
 
116
 
 
117
static Tag escaped_tags[] = {
 
118
        { "<center>", NULL },
 
119
        { "</center>", NULL },
 
120
        { "<p>", "\n" },
 
121
        { "</p>", NULL },
 
122
        { "<B>", "<b>" },
 
123
        { "</B>", "</b>" },
 
124
        { "<I>", "<i>" },
 
125
        { "</I>", "</i>" },
 
126
        { "<u>", "<u>" },
 
127
        { "</u>", "</u>" },
 
128
        { "&", "&amp;" },
 
129
        { NULL, NULL }
 
130
};
 
131
 
 
132
char *
 
133
utils_escape_notify_message (const char *src)
 
134
{
 
135
        const char *p = src;
 
136
        GString *escaped;
 
137
 
 
138
        /* Filter the source text and get rid of some HTML tags since the
 
139
         * notification spec only allows a subset of HTML.  Substitute
 
140
         * HTML code for characters like & that are invalid in HTML.
 
141
         */
 
142
 
 
143
        escaped = g_string_sized_new (strlen (src) + 5);
 
144
        while (*p) {
 
145
                Tag *t = &escaped_tags[0];
 
146
                gboolean found = FALSE;
 
147
 
 
148
                while (t->tag) {
 
149
                        if (strncasecmp (p, t->tag, strlen (t->tag)) == 0) {
 
150
                                p += strlen (t->tag);
 
151
                                if (t->replacement)
 
152
                                        g_string_append (escaped, t->replacement);
 
153
                                found = TRUE;
 
154
                                break;
 
155
                        }
 
156
                        t++;
 
157
                }
 
158
                if (!found)
 
159
                        g_string_append_c (escaped, *p++);
 
160
        }
 
161
 
 
162
        return g_string_free (escaped, FALSE);
 
163
}
 
164
 
 
165
char *
 
166
utils_create_mobile_connection_id (const char *provider, const char *plan_name)
 
167
{
 
168
        g_return_val_if_fail (provider != NULL, NULL);
 
169
 
 
170
        if (plan_name)
 
171
                return g_strdup_printf ("%s %s", provider, plan_name);
 
172
 
 
173
        /* The %s is a mobile provider name, eg "T-Mobile" */
 
174
        return g_strdup_printf (_("%s connection"), provider);
 
175
}
 
176
 
 
177
void
 
178
utils_show_error_dialog (const char *title,
 
179
                         const char *text1,
 
180
                         const char *text2,
 
181
                         gboolean modal,
 
182
                         GtkWindow *parent)
 
183
{
 
184
        GtkWidget *err_dialog;
 
185
 
 
186
        g_return_if_fail (text1 != NULL);
 
187
 
 
188
        err_dialog = gtk_message_dialog_new (parent,
 
189
                                             GTK_DIALOG_DESTROY_WITH_PARENT,
 
190
                                             GTK_MESSAGE_ERROR,
 
191
                                             GTK_BUTTONS_CLOSE,
 
192
                                             "%s",
 
193
                                             text1);
 
194
 
 
195
        if (text2)
 
196
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), "%s", text2);
 
197
        if (title)
 
198
                gtk_window_set_title (GTK_WINDOW (err_dialog), title);
 
199
 
 
200
        if (modal) {
 
201
                gtk_dialog_run (GTK_DIALOG (err_dialog));
 
202
                gtk_widget_destroy (err_dialog);
 
203
        } else {
 
204
                g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
 
205
                g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
 
206
 
 
207
                gtk_widget_show_all (err_dialog);
 
208
                gtk_window_present (GTK_WINDOW (err_dialog));
 
209
        }
 
210
}
 
211
 
 
212
 
 
213
gboolean
 
214
utils_char_is_ascii_print (char character)
 
215
{
 
216
        return g_ascii_isprint (character);
 
217
}
 
218
 
 
219
gboolean
 
220
utils_char_is_ascii_digit (char character)
 
221
{
 
222
        return g_ascii_isdigit (character);
 
223
}
 
224
 
 
225
gboolean
 
226
utils_char_is_ascii_ip4_address (char character)
 
227
{
 
228
        return g_ascii_isdigit (character) || character == '.';
 
229
}
 
230
 
 
231
gboolean
 
232
utils_char_is_ascii_ip6_address (char character)
 
233
{
 
234
        return g_ascii_isxdigit (character) || character == ':';
 
235
}
 
236
 
 
237
gboolean
 
238
utils_char_is_ascii_apn (char character)
 
239
{
 
240
        return g_ascii_isalnum (character)
 
241
               || character == '.'
 
242
               || character == '_'
 
243
               || character == '-';
 
244
}
 
245
 
 
246
/**
 
247
 * Filters the characters from a text that was just input into GtkEditable.
 
248
 * Returns FALSE, if after filtering no characters were left. TRUE means,
 
249
 * that valid characters were added and the content of the GtkEditable changed.
 
250
 **/
 
251
gboolean
 
252
utils_filter_editable_on_insert_text (GtkEditable *editable,
 
253
                                      const gchar *text,
 
254
                                      gint length,
 
255
                                      gint *position,
 
256
                                      void *user_data,
 
257
                                      UtilsFilterGtkEditableFunc validate_character,
 
258
                                      gpointer block_func)
 
259
{
 
260
        int i, count = 0;
 
261
        gchar *result = g_new (gchar, length+1);
 
262
 
 
263
        for (i = 0; i < length; i++) {
 
264
                if (validate_character (text[i]))
 
265
                        result[count++] = text[i];
 
266
        }
 
267
        result[count] = 0;
 
268
 
 
269
        if (count > 0) {
 
270
                if (block_func) {
 
271
                        g_signal_handlers_block_by_func (G_OBJECT (editable),
 
272
                                                         G_CALLBACK (block_func),
 
273
                                                         user_data);
 
274
                }
 
275
                gtk_editable_insert_text (editable, result, count, position);
 
276
                if (block_func) {
 
277
                        g_signal_handlers_unblock_by_func (G_OBJECT (editable),
 
278
                                                           G_CALLBACK (block_func),
 
279
                                                           user_data);
 
280
                }
 
281
        }
 
282
        g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
 
283
 
 
284
        g_free (result);
 
285
 
 
286
        return count > 0;
 
287
}
 
288