summaryrefslogtreecommitdiffstats
path: root/perl-install
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.org>2004-06-24 05:32:13 +0000
committerOlivier Blin <oblin@mandriva.org>2004-06-24 05:32:13 +0000
commitfb85fae46c73c7cab5d5965fa1281c76a8007bad (patch)
tree7513b5ae2b97773c0698086ef7ba98ef673ea242 /perl-install
parentfa6ef617411bdf2082f01cd02a977207f41840a8 (diff)
downloaddrakx-backup-do-not-use-fb85fae46c73c7cab5d5965fa1281c76a8007bad.tar
drakx-backup-do-not-use-fb85fae46c73c7cab5d5965fa1281c76a8007bad.tar.gz
drakx-backup-do-not-use-fb85fae46c73c7cab5d5965fa1281c76a8007bad.tar.bz2
drakx-backup-do-not-use-fb85fae46c73c7cab5d5965fa1281c76a8007bad.tar.xz
drakx-backup-do-not-use-fb85fae46c73c7cab5d5965fa1281c76a8007bad.zip
properly handle ascii WEP keys (#9884)
Diffstat (limited to 'perl-install')
-rw-r--r--perl-install/network/network.pm3
-rw-r--r--perl-install/network/tools.pm17
2 files changed, 19 insertions, 1 deletions
diff --git a/perl-install/network/network.pm b/perl-install/network/network.pm
index 728e0f901..da773c8c2 100644
--- a/perl-install/network/network.pm
+++ b/perl-install/network/network.pm
@@ -168,7 +168,7 @@ sub write_interface_conf {
$intf->{BOOTPROTO} =~ s/dhcp.*/dhcp/;
- local $intf->{WIRELESS_ENC_KEY} = qq("$intf->{WIRELESS_ENC_KEY}") if $intf->{WIRELESS_ENC_KEY} !~ /"/;
+ local $intf->{WIRELESS_ENC_KEY} = network::tools::convert_wep_key_for_iwconfig($intf->{WIRELESS_ENC_KEY});
setVarsInSh($file, $intf, qw(DEVICE BOOTPROTO IPADDR NETMASK NETWORK BROADCAST ONBOOT HWADDR MII_NOT_SUPPORTED),
qw(WIRELESS_MODE WIRELESS_ESSID WIRELESS_NWID WIRELESS_FREQ WIRELESS_SENS WIRELESS_RATE WIRELESS_ENC_KEY WIRELESS_RTS WIRELESS_FRAG WIRELESS_IWCONFIG WIRELESS_IWSPY WIRELESS_IWPRIV),
if_($intf->{BOOTPROTO} eq "dhcp", qw(DHCP_HOSTNAME NEEDHOSTNAME))
@@ -344,6 +344,7 @@ sub read_all_conf {
if (/^ifcfg-([A-Za-z0-9.:]+)$/ && $1 ne 'lo') {
my $intf = findIntf($intf, $1);
add2hash($intf, { getVarsFromSh("$::prefix/etc/sysconfig/network-scripts/$_") });
+ $intf->{WIRELESS_ENC_KEY} = network::tools::get_wep_key_from_iwconfig($intf->{WIRELESS_ENC_KEY});
}
}
$netcnx->{type} or probe_netcnx_type($::prefix, $netc, $intf, $netcnx);
diff --git a/perl-install/network/tools.pm b/perl-install/network/tools.pm
index 4726e1350..e49e8dc2b 100644
--- a/perl-install/network/tools.pm
+++ b/perl-install/network/tools.pm
@@ -189,4 +189,21 @@ sub reread_net_conf {
network::network::probe_netcnx_type('', $netc, $intf, $netcnx);
}
+sub convert_wep_key_for_iwconfig {
+ #- 5 or 13 characters, consider the key as ASCII and prepend "s:"
+ #- else consider the key as hexadecimal, do not strip dashes
+ #- always quote the key as string
+ my ($key) = @_;
+ unquotify \$key;
+ member(length($key), (5, 13)) ? qq("s:$key") : qq("$key");
+}
+
+sub get_wep_key_from_iwconfig {
+ #- strip "s:" if the key is 5 or 13 characters (ASCII)
+ #- else the key as hexadecimal, do not modify
+ my ($key) = @_;
+ $key =~ s/^s:// if member(length($key), (7,15));
+ $key;
+}
+
1;
href='#n270'>270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
/*
 * Get kernel symbol table(s) and other relevant module info.
 *
 * Add module_name_list and l_module_name_list.
 *   Keith Owens <kaos@ocs.com.au> November 1999.
 * Björn Ekwall <bj0rn@blox.se> in February 1999 (C)
 * Initial work contributed by Richard Henderson <rth@tamu.edu>
 *
 * This file is part of the Linux modutils.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "util.h"
#include "module.h"
#include "obj.h"
#include "modstat.h"

struct module_stat *module_stat;
size_t n_module_stat;
char *module_name_list;
size_t l_module_name_list;
struct module_symbol *ksyms;
size_t nksyms;
int k_new_syscalls;

static void *old_kernsym;

/************************************************************************/
static void drop(void)
{
	/*
	 * Clean the slate for multiple runs
	 */
	if (module_stat) {
		struct module_stat *m;
		int i;

		for (i = 0, m = module_stat; i < n_module_stat; ++i, ++m) {
			if (m->syms)
				free(m->syms);
			if (m->refs)
				free(m->refs);
		}
		free(module_stat);
		module_stat = NULL;
		n_module_stat = 0;
	}
	if (module_name_list) {
		free(module_name_list);
		module_name_list = NULL;
		l_module_name_list = 0;
	}
	if (ksyms) {
		free(ksyms);
		ksyms = NULL;
		nksyms = 0;
	}
	if (old_kernsym) {
		free(old_kernsym);
		old_kernsym = NULL;
	}
}

static int new_get_kernel_info(int type)
{
	struct module_stat *modules;
	struct module_stat *m;
	struct module_symbol *syms;
	struct module_symbol *s;
	size_t ret;
	size_t bufsize;
	size_t nmod;
	size_t nsyms;
	size_t i;
	size_t j;
	char *module_names;
	char *mn;

	drop();

	/*
	 * Collect the loaded modules
	 */
	module_names = xmalloc(bufsize = 256);
	while (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
		if (errno != ENOSPC) {
			error("QM_MODULES: %m\n");
			return 0;
		}
		module_names = xrealloc(module_names, bufsize = ret);
	}
	module_name_list = module_names;
	l_module_name_list = bufsize;
	n_module_stat = nmod = ret;
	module_stat = modules = xmalloc(nmod * sizeof(struct module_stat));
	memset(modules, 0, nmod * sizeof(struct module_stat));

	/* Collect the info from the modules */
	for (i = 0, mn = module_names, m = modules;
	     i < nmod;
	     ++i, ++m, mn += strlen(mn) + 1) {
		struct module_info info;

		m->name = mn;
		if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
			if (errno == ENOENT) {
			/* The module was removed out from underneath us. */
				m->flags = NEW_MOD_DELETED;
				continue;
			}
			/* else oops */
			error("module %s: QM_INFO: %m", mn);
			return 0;
		}

		m->addr = info.addr;

		if (type & K_INFO) {
			m->size = info.size;
			m->flags = info.flags;
			m->usecount = info.usecount;
			m->modstruct = info.addr;
		}

		if (type & K_REFS) {
			int mm;
			char *mrefs;
			char *mr;

			mrefs = xmalloc(bufsize = 64);
			while (query_module(mn, QM_REFS, mrefs, bufsize, &ret)) {
				if (errno != ENOSPC) {
					error("QM_REFS: %m");
					return 1;
				}
				mrefs = xrealloc(mrefs, bufsize = ret);
			}
			for (j = 0, mr = mrefs;
			     j < ret;
			     ++j, mr += strlen(mr) + 1) {
				for (mm = 0; mm < i; ++mm) {
					if (strcmp(mr, module_stat[mm].name) == 0) {
						m->nrefs += 1;
						m->refs = xrealloc(m->refs, m->nrefs * sizeof(struct module_stat **));
						m->refs[m->nrefs - 1] = module_stat + mm;
						break;
					}
				}
			}
			free(mrefs);
		}

		if (type & K_SYMBOLS) { /* Want info about symbols */
			syms = xmalloc(bufsize = 1024);
			while (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
				if (errno == ENOSPC) {
					syms = xrealloc(syms, bufsize = ret);
					continue;
				}
				if (errno == ENOENT) {
					/*
					 * The module was removed out
					 * from underneath us.
					 */
					m->flags = NEW_MOD_DELETED;
					free(syms);
					goto next;
				} else {
					error("module %s: QM_SYMBOLS: %m", mn);
					return 0;
				}
			}
			nsyms = ret;

			m->nsyms = nsyms;
			m->syms = syms;

			/* Convert string offsets to string pointers */
			for (j = 0, s = syms; j < nsyms; ++j, ++s)
				s->name += (unsigned long) syms;
		}
		next:
	}

	if (type & K_SYMBOLS) { /* Want info about symbols */
		/* Collect the kernel's symbols.  */
		syms = xmalloc(bufsize = 16 * 1024);
		while (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
			if (errno != ENOSPC) {
				error("kernel: QM_SYMBOLS: %m");
				return 0;
			}
			syms = xrealloc(syms, bufsize = ret);
		}
		nksyms = nsyms = ret;
		ksyms = syms;

		/* Convert string offsets to string pointers */
		for (j = 0, s = syms; j < nsyms; ++j, ++s)
			s->name += (unsigned long) syms;
	}

	return 1;
}

#ifdef COMPAT_2_0
/************************************************************************/

#define mscan(offs,siz,ptr) \
	if (lseek(kmem_fd, (off_t)(offs), SEEK_SET) == -1 || \
	    read(kmem_fd, (ptr), (siz)) != (siz)) { \
		if (kmem_fd != -1) \
			close(kmem_fd); \
		error("kmem: %m"); \
		return 0; \
	}

#define OLD_MOD_RUNNING 1
#define OLD_MOD_DELETED 2
#define OLD_MOD_VISITED   0x20000000

/* Fetch all the symbols and divvy them up as appropriate for the modules.  */
static int old_get_kernel_info(int type)
{
	struct old_kernel_sym *kernsym;
	struct old_kernel_sym *k;
	struct module_stat *module;
	struct module_stat *mod;
	struct module_symbol *s = NULL;
	int kmem_fd = -1;
	int nkernsym;
	int nmod;
	int nm;
	int nms;
	int i;

	drop();
	module_name_list = xmalloc(1);
	*module_name_list = '\0';

	if ((nkernsym = get_kernel_syms(NULL)) < 0) {
		error("get_kernel_syms: %m");
		return 0;
	}
	kernsym = k = xmalloc(nkernsym * sizeof(struct old_kernel_sym));
	old_kernsym = kernsym;
	if (get_kernel_syms(kernsym) != nkernsym) {
		error("inconsistency with get_kernel_syms -- is someone else "
		      "playing with modules?");
		free(kernsym);
		return 0;
	}

	/* Number of modules */
	for (k = kernsym, nmod = 0, i = 0; i < nkernsym; ++i, ++k) {
		if (k->name[0] == '#') {
			if (k->name[1]) {
				++nmod;
				i = strlen(k->name+1) + 1;
				module_name_list =
					xrealloc(module_name_list,
					l_module_name_list + i);
				strcpy(module_name_list+l_module_name_list,	/* safe, xrealloc */
					k->name+1);
				l_module_name_list += i;	/* NUL separated strings */
			}
			else
				break;
		}
	}
	module_stat = mod = module = xmalloc(nmod * sizeof(struct module_stat));
	memset(module, 0, nmod * sizeof(struct module_stat));
	n_module_stat = nmod;

	/*
	 * Will we need kernel internal info?
	 */
	if ((type & K_INFO) || (type & K_REFS)) {
		if ((kmem_fd = open("/dev/kmem", O_RDONLY)) < 0) {
			perror("ksyms: open /dev/kmem");
			return 0;
		}
	}

	/*
	 * Collect the module information.
	 */
	for (k = kernsym, nm = 0, i = 0; i < nkernsym; ++i, ++k) {
		if (k->name[0] == '#') {
			struct old_kernel_sym *p;
			struct old_module info;

			if (k->name[1] == '\0')
				break; /* kernel resident symbols follow */
			/* else normal module */

			module = mod++;
			++nm;
			module->name = k->name + 1;
			module->modstruct = k->value;

			if ((type & K_INFO) || (type & K_REFS)) {
				long tmp;
				/*
				 * k->value is the address of the
				 * struct old_module
				 * in the kernel (for use via /dev/kmem)
				 */
				mscan(k->value, sizeof(info), &info);
				module->addr = info.addr;
				module->size = info.size * getpagesize();

				mscan(info.addr, sizeof(long), &tmp);
				module->flags = info.state &
						(OLD_MOD_RUNNING | OLD_MOD_DELETED);
				module->flags |= NEW_MOD_USED_ONCE; /* Cheat */
				if (tmp & OLD_MOD_AUTOCLEAN)
					module->flags |= NEW_MOD_AUTOCLEAN;
				if (tmp & OLD_MOD_VISITED)
					module->flags |= NEW_MOD_VISITED;

				module->usecount = tmp & ~(OLD_MOD_AUTOCLEAN | OLD_MOD_VISITED);
			}

			if ((type & K_REFS) && info.ref) {
				struct old_module_ref mr;
				int j;
				unsigned long ref = info.ref;

				do {
					mscan(ref, sizeof(struct old_module_ref), &mr);
					for (j = 0; j < nm -1; ++j) {
						if (mr.module == module_stat[j].modstruct) {
							module->nrefs += 1;
							module->refs = xrealloc(module->refs, module->nrefs * sizeof(struct module_stat **));
							module->refs[module->nrefs - 1] = module_stat + j;
							break;
						}
					}
				} while ((ref = mr.next) != 0);
			}

			if (!(type & K_SYMBOLS))
				continue;
			/*
			 * Find out how many symbols this module has.
			 */
			for (nms = 0, p = k+1; p->name[0] != '#'; ++p)
				++nms;
			s = xmalloc(nms * sizeof(struct module_symbol));
			module->syms = s;
			module->nsyms = nms;
		} else if (type & K_SYMBOLS) { /* Want info about symbols */
			s->name = (unsigned long) k->name;
			s->value = k->value;
			++s;
		}
	}
	if ((type & K_INFO) || (type & K_REFS)) {
		if (kmem_fd != -1)
			close(kmem_fd);
	}

	/*
	 * Kernel resident symbols follows
	 */
	if (type & K_SYMBOLS) { /* Want info about symbols */
		if (k->name[0] == '#')
			++k;
		nksyms = nkernsym - (k - kernsym);
		if (nksyms) {
			ksyms = s = xmalloc(nksyms * sizeof(struct module_symbol));
			for (i = 0; i < nksyms; ++i, ++k) {
				if (k->name[0] != '#') {
					s->name = (unsigned long) k->name;
					s->value = k->value;
					++s;
				}
			}
			nksyms = s - ksyms;
		} else
			ksyms = NULL;
	}

	return 1;
}