* Added some authentication config stuff to the settings. Now you can override
the detected defaults with your own values. * Implemented joining open and WEP networks - this is pretty much untested, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39794 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
SubDir HAIKU_TOP src servers net ;
|
SubDir HAIKU_TOP src servers net ;
|
||||||
|
|
||||||
UsePrivateHeaders app net storage ;
|
UsePrivateHeaders app net shared storage ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
|
||||||
|
: true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ;
|
||||||
|
|
||||||
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp headers ] ;
|
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp headers ] ;
|
||||||
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
|
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
#include <NetworkDevice.h>
|
||||||
#include <NetworkInterface.h>
|
#include <NetworkInterface.h>
|
||||||
#include <NetworkRoster.h>
|
#include <NetworkRoster.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
@@ -38,10 +39,16 @@
|
|||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
#include "AutoconfigLooper.h"
|
#include "AutoconfigLooper.h"
|
||||||
#include "Services.h"
|
#include "Services.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
# include <net80211/ieee80211_ioctl.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<std::string, AutoconfigLooper*> LooperMap;
|
typedef std::map<std::string, AutoconfigLooper*> LooperMap;
|
||||||
|
|
||||||
@@ -108,6 +115,52 @@ static const address_family kFamilies[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - private functions
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
set_80211(const char* name, int32 type, void* data,
|
||||||
|
int32 length = 0, int32 value = 0)
|
||||||
|
{
|
||||||
|
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
struct ieee80211req ireq;
|
||||||
|
strlcpy(ireq.i_name, name, IF_NAMESIZE);
|
||||||
|
ireq.i_type = type;
|
||||||
|
ireq.i_val = value;
|
||||||
|
ireq.i_len = length;
|
||||||
|
ireq.i_data = data;
|
||||||
|
|
||||||
|
if (ioctl(socket, SIOCS80211, &ireq, sizeof(struct ieee80211req)) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
translate_wep_key(const char*& buffer, char* key)
|
||||||
|
{
|
||||||
|
memset(key, 0, IEEE80211_KEYBUF_SIZE);
|
||||||
|
|
||||||
|
// TODO: support possibility to set them all
|
||||||
|
if (buffer[0] != '\0') {
|
||||||
|
int32 length = strlcpy(key, buffer, IEEE80211_KEYBUF_SIZE);
|
||||||
|
buffer += length;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - exported functions
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
get_address_family(const char* argument)
|
get_address_family(const char* argument)
|
||||||
{
|
{
|
||||||
@@ -766,6 +819,10 @@ NetServer::_HandleDeviceMonitor(BMessage* message)
|
|||||||
status_t
|
status_t
|
||||||
NetServer::_JoinNetwork(const BMessage& message, const char* name)
|
NetServer::_JoinNetwork(const BMessage& message, const char* name)
|
||||||
{
|
{
|
||||||
|
const char* deviceName;
|
||||||
|
if (message.FindString("device", &deviceName) != B_OK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
BNetworkAddress address;
|
BNetworkAddress address;
|
||||||
message.FindFlat("address", &address);
|
message.FindFlat("address", &address);
|
||||||
|
|
||||||
@@ -781,10 +838,10 @@ NetServer::_JoinNetwork(const BMessage& message, const char* name)
|
|||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
uint32 cookie = 0;
|
uint32 cookie = 0;
|
||||||
BMessage network;
|
BMessage networkMessage;
|
||||||
while (fSettings.GetNextNetwork(cookie, network) == B_OK) {
|
while (fSettings.GetNextNetwork(cookie, networkMessage) == B_OK) {
|
||||||
const char* networkName;
|
const char* networkName;
|
||||||
if (network.FindString("name", &networkName) == B_OK
|
if (networkMessage.FindString("name", &networkName) == B_OK
|
||||||
&& name != NULL && address.Family() != AF_LINK
|
&& name != NULL && address.Family() != AF_LINK
|
||||||
&& !strcmp(name, networkName)) {
|
&& !strcmp(name, networkName)) {
|
||||||
found = true;
|
found = true;
|
||||||
@@ -792,7 +849,7 @@ NetServer::_JoinNetwork(const BMessage& message, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* mac;
|
const char* mac;
|
||||||
if (network.FindString("mac", &mac) == B_OK
|
if (networkMessage.FindString("mac", &mac) == B_OK
|
||||||
&& address.Family() == AF_LINK) {
|
&& address.Family() == AF_LINK) {
|
||||||
BNetworkAddress link(AF_LINK, mac);
|
BNetworkAddress link(AF_LINK, mac);
|
||||||
if (link == address) {
|
if (link == address) {
|
||||||
@@ -804,10 +861,101 @@ NetServer::_JoinNetwork(const BMessage& message, const char* name)
|
|||||||
|
|
||||||
const char* password;
|
const char* password;
|
||||||
if (message.FindString("password", &password) != B_OK && found)
|
if (message.FindString("password", &password) != B_OK && found)
|
||||||
password = network.FindString("password");
|
password = networkMessage.FindString("password");
|
||||||
|
|
||||||
|
// Get network
|
||||||
|
BNetworkDevice device(deviceName);
|
||||||
|
wireless_network network;
|
||||||
|
if ((address.Family() != AF_LINK
|
||||||
|
|| device.GetNetwork(address, network) != B_OK)
|
||||||
|
&& device.GetNetwork(name, network) != B_OK) {
|
||||||
|
// We did not find a network - just ignore that, and continue
|
||||||
|
// with some defaults
|
||||||
|
strlcpy(network.name, name, sizeof(network.name));
|
||||||
|
network.address = address;
|
||||||
|
network.authentication_mode = B_NETWORK_AUTHENTICATION_NONE;
|
||||||
|
network.cipher = 0;
|
||||||
|
network.group_cipher = 0;
|
||||||
|
network.key_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* string;
|
||||||
|
if (message.FindString("authentication", &string) == B_OK
|
||||||
|
|| (found && networkMessage.FindString("authentication", &string)
|
||||||
|
== B_OK)) {
|
||||||
|
if (!strcasecmp(string, "wpa2")) {
|
||||||
|
network.authentication_mode = B_NETWORK_AUTHENTICATION_WPA2;
|
||||||
|
network.key_mode = B_KEY_MODE_IEEE802_1X;
|
||||||
|
network.cipher = network.group_cipher = B_NETWORK_CIPHER_CCMP;
|
||||||
|
} else if (!strcasecmp(string, "wpa")) {
|
||||||
|
network.authentication_mode = B_NETWORK_AUTHENTICATION_WPA;
|
||||||
|
network.key_mode = B_KEY_MODE_IEEE802_1X;
|
||||||
|
network.cipher = network.group_cipher = B_NETWORK_CIPHER_TKIP;
|
||||||
|
} else if (!strcasecmp(string, "wep")) {
|
||||||
|
network.authentication_mode = B_NETWORK_AUTHENTICATION_WEP;
|
||||||
|
network.key_mode = B_KEY_MODE_NONE;
|
||||||
|
network.cipher = network.group_cipher = B_NETWORK_CIPHER_WEP_40;
|
||||||
|
} else if (strcasecmp(string, "none") && strcasecmp(string, "open"))
|
||||||
|
fprintf(stderr, "%s: invalid authentication mode.\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: if password is still NULL, ask password manager once we have one
|
// TODO: if password is still NULL, ask password manager once we have one
|
||||||
// TODO: join for real!
|
// TODO: remove the clear text settings password once we have
|
||||||
|
|
||||||
|
if (password == NULL
|
||||||
|
&& network.authentication_mode > B_NETWORK_AUTHENTICATION_NONE)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
// Join the specified network with the specified authentication method
|
||||||
|
|
||||||
|
if (network.authentication_mode < B_NETWORK_AUTHENTICATION_WPA) {
|
||||||
|
// we join the network ourselves
|
||||||
|
status_t status = set_80211(deviceName, IEEE80211_IOC_SSID,
|
||||||
|
network.name, strlen(network.name));
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "%s: joining SSID failed: %s\n", name,
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network.authentication_mode == B_NETWORK_AUTHENTICATION_WEP) {
|
||||||
|
status = set_80211(deviceName, IEEE80211_IOC_WEP, NULL, 0,
|
||||||
|
IEEE80211_WEP_ON);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "%s: turning on WEP failed: %s\n", name,
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* buffer = password;
|
||||||
|
|
||||||
|
// set key
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
char key[IEEE80211_KEYBUF_SIZE];
|
||||||
|
int32 keyLength = translate_wep_key(buffer, key);
|
||||||
|
status = set_80211(deviceName, IEEE80211_IOC_WEPKEY, key,
|
||||||
|
keyLength);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
status = set_80211(deviceName, IEEE80211_IOC_WEPKEY, NULL, 0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "%s: setting WEP keys failed: %s\n", name,
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: join via wpa_supplicant
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ const static settings_template kNetworkTemplate[] = {
|
|||||||
{B_STRING_TYPE, "name", NULL, true},
|
{B_STRING_TYPE, "name", NULL, true},
|
||||||
{B_STRING_TYPE, "mac", NULL},
|
{B_STRING_TYPE, "mac", NULL},
|
||||||
{B_STRING_TYPE, "password", NULL},
|
{B_STRING_TYPE, "password", NULL},
|
||||||
// TODO: possibility to specify encryption modes
|
{B_STRING_TYPE, "authentication", NULL},
|
||||||
|
{B_STRING_TYPE, "cipher", NULL},
|
||||||
|
{B_STRING_TYPE, "key", NULL},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user