GUACAMOLE-513: Merge support for Wake-on-LAN.

This commit is contained in:
Mike Jumper 2020-06-09 01:15:11 -07:00 committed by GitHub
commit 65c07b75cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 701 additions and 3 deletions

View File

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_COMMON_DEFAULTS_H
#define GUAC_COMMON_DEFAULTS_H
/**
* The default number of seconds to wait after sending the Wake-on-LAN packet
* for the destination host to start responding.
*/
#define GUAC_WOL_DEFAULT_BOOT_WAIT_TIME 60
#endif /* GUAC_COMMON_DEFAULTS_H */

View File

@ -69,7 +69,9 @@ libguacinc_HEADERS = \
guacamole/user.h \
guacamole/user-constants.h \
guacamole/user-fntypes.h \
guacamole/user-types.h
guacamole/user-types.h \
guacamole/wol.h \
guacamole/wol-constants.h
noinst_HEADERS = \
id.h \
@ -104,7 +106,8 @@ libguac_la_SOURCES = \
user.c \
user-handlers.c \
user-handshake.c \
wait-fd.c
wait-fd.c \
wol.c
# Compile WebP support if available
if ENABLE_WEBP

View File

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_WOL_CONSTANTS_H
#define GUAC_WOL_CONSTANTS_H
/**
* Header file that provides constants and defaults related to libguac
* Wake-on-LAN support.
*
* @file wol-constants.h
*/
/**
* The value for the local IPv4 broadcast address.
*/
#define GUAC_WOL_LOCAL_IPV4_BROADCAST "255.255.255.255"
/**
* The size of the magic Wake-on-LAN packet to send to wake a remote host. This
* consists of 6 bytes of 0xFF, and then the MAC address repeated 16 times.
* https://en.wikipedia.org/wiki/Wake-on-LAN#Magic_packet
*/
#define GUAC_WOL_PACKET_SIZE 102
/**
* The port number that the magic packet should contain as the destination. In
* reality this doesn't matter all that much, since the packet is not usually
* processed by a full IP stack, but defining one is considered a standard
* practice.
*/
#define GUAC_WOL_PORT 9
#endif /* GUAC_WOL_CONSTANTS_H */

View File

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_WOL_H
#define GUAC_WOL_H
/**
* Header that provides functions and structures related to Wake-on-LAN
* support in libguac.
*
* @file wol.h
*/
#include "wol-constants.h"
/**
* Send the wake-up packet to the specified destination, returning zero if the
* wake was sent successfully, or non-zero if an error occurs sending the
* wake packet. Note that the return value does not specify whether the
* system actually wakes up successfully, only whether or not the packet
* is transmitted.
*
* @param mac_addr
* The MAC address to place in the magic Wake-on-LAN packet.
*
* @param broadcast_addr
* The broadcast address to which to send the magic Wake-on-LAN packet.
*
* @return
* Zero if the packet is successfully sent to the destination; non-zero
* if the packet cannot be sent.
*/
int guac_wol_wake(const char* mac_addr, const char* broadcast_addr);
#endif /* GUAC_WOL_H */

150
src/libguac/wol.c Normal file
View File

@ -0,0 +1,150 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "guacamole/wol.h"
/**
* Generate the magic Wake-on-LAN (WoL) packet for the specified MAC address
* and place it in the character array.
*
* @param packet
* The character array that will contain the generated packet.
*
* @param mac_address
* The unsigned int representation of the MAC address to place in the packet.
*/
static void __guac_wol_create_magic_packet(unsigned char packet[],
unsigned int mac_address[]) {
int i;
unsigned char mac[6];
/* Concurrently fill the first part of the packet with 0xFF, and copy the
MAC address from the int array to the char array. */
for (i = 0; i < 6; i++) {
packet[i] = 0xFF;
mac[i] = mac_address[i];
}
/* Copy the MAC address contents into the char array that is storing
the rest of the packet. */
for (i = 1; i <= 16; i++) {
memcpy(&packet[i * 6], &mac, 6 * sizeof(unsigned char));
}
}
/**
* Send the magic Wake-on-LAN (WoL) packet to the specified broadcast address,
* returning the number of bytes sent, or zero if any error occurred and nothing
* was sent.
*
* @param broadcast_addr
* The broadcast address to which to send the magic WoL packet.
*
* @param packet
* The magic WoL packet to send.
*
* @return
* The number of bytes sent, or zero if nothing could be sent.
*/
static ssize_t __guac_wol_send_packet(const char* broadcast_addr,
unsigned char packet[]) {
struct sockaddr_in wol_dest;
int wol_socket;
/* Determine the IP version, starting with IPv4. */
wol_dest.sin_port = htons(GUAC_WOL_PORT);
wol_dest.sin_family = AF_INET;
if (inet_pton(AF_INET, broadcast_addr, &(wol_dest.sin_addr)) == 0) {
wol_dest.sin_family = AF_INET6;
if (inet_pton(AF_INET6, broadcast_addr, &(wol_dest.sin_addr)) == 0)
return 0;
}
/* Set up socket for IPv4 broadcast. */
if (wol_dest.sin_family == AF_INET) {
int wol_bcast = 1;
wol_socket = socket(AF_INET, SOCK_DGRAM, 0);
/* Attempt to set broadcast; exit with error if this fails. */
if (setsockopt(wol_socket, SOL_SOCKET, SO_BROADCAST, &wol_bcast,
sizeof(wol_bcast)) < 0) {
close(wol_socket);
return 0;
}
}
/* Set up socket for IPv6 multicast. */
else {
wol_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
/* Stick to a single hop for now. */
int hops = 1;
if (setsockopt(wol_socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,
sizeof(hops))) {
close(wol_socket);
return 0;
}
}
/* Send the packet and return number of bytes sent. */
int bytes = sendto(wol_socket, packet, GUAC_WOL_PACKET_SIZE, 0,
(struct sockaddr*) &wol_dest, sizeof(wol_dest));
close(wol_socket);
return bytes;
}
int guac_wol_wake(const char* mac_addr, const char* broadcast_addr) {
unsigned char wol_packet[GUAC_WOL_PACKET_SIZE];
unsigned int dest_mac[6];
/* Parse mac address and return with error if parsing fails. */
if (sscanf(mac_addr, "%x:%x:%x:%x:%x:%x",
&(dest_mac[0]), &(dest_mac[1]), &(dest_mac[2]),
&(dest_mac[3]), &(dest_mac[4]), &(dest_mac[5])) != 6) {
return -1;
}
/* Generate the magic packet. */
__guac_wol_create_magic_packet(wol_packet, dest_mac);
/* Send the packet and record bytes sent. */
int bytes_sent = __guac_wol_send_packet(broadcast_addr, wol_packet);
/* Return 0 if bytes were sent, otherwise return an error. */
if (bytes_sent)
return 0;
return -1;
}

View File

@ -69,6 +69,7 @@
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
#include <guacamole/wol.h>
#include <winpr/error.h>
#include <winpr/synch.h>
#include <winpr/wtypes.h>
@ -529,6 +530,20 @@ void* guac_rdp_client_thread(void* data) {
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_rdp_settings* settings = rdp_client->settings;
/* If Wake-on-LAN is enabled, try to wake. */
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
}
/* If audio enabled, choose an encoder */
if (settings->audio_enabled) {

View File

@ -17,6 +17,7 @@
* under the License.
*/
#include "common/defaults.h"
#include "common/string.h"
#include "config.h"
#include "resolution.h"
@ -28,6 +29,7 @@
#include <guacamole/client.h>
#include <guacamole/string.h>
#include <guacamole/user.h>
#include <guacamole/wol-constants.h>
#include <winpr/crt.h>
#include <winpr/wtypes.h>
@ -117,6 +119,11 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
"disable-copy",
"disable-paste",
"wol-send-packet",
"wol-mac-addr",
"wol-broadcast-addr",
"wol-wait-time",
NULL
};
@ -581,6 +588,34 @@ enum RDP_ARGS_IDX {
*/
IDX_DISABLE_PASTE,
/**
* Whether or not to send the magic Wake-on-LAN (WoL) packet to the host
* prior to attempting to connect. Non-zero values will enable sending
* the WoL packet, while zero will disable this functionality. By default
* the WoL packet is not sent.
*/
IDX_WOL_SEND_PACKET,
/**
* The MAC address to put in the magic WoL packet for the host that should
* be woken up.
*/
IDX_WOL_MAC_ADDR,
/**
* The broadcast address to which to send the magic WoL packet to wake up
* the remote host.
*/
IDX_WOL_BROADCAST_ADDR,
/**
* The amount of time, in seconds, to wait after sending the WoL packet
* before attempting to connect to the host. This should be a reasonable
* amount of time to allow the remote host to fully boot and respond to
* network connection requests. The default amount of time is 60 seconds.
*/
IDX_WOL_WAIT_TIME,
RDP_ARGS_COUNT
};
@ -1072,6 +1107,37 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_DISABLE_PASTE, 0);
/* Parse Wake-on-LAN (WoL) settings */
settings->wol_send_packet =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_WOL_SEND_PACKET, 0);
if (settings->wol_send_packet) {
/* If WoL has been requested but no MAC address given, log a warning. */
if(strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) {
guac_user_log(user, GUAC_LOG_WARNING, "WoL requested but no MAC ",
"address specified. WoL will not be sent.");
settings->wol_send_packet = 0;
}
/* Parse the WoL MAC address. */
settings->wol_mac_addr =
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_WOL_MAC_ADDR, NULL);
/* Parse the WoL broadcast address. */
settings->wol_broadcast_addr =
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST);
/* Parse the WoL wait time. */
settings->wol_wait_time =
guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME);
}
/* Success */
return settings;
@ -1134,6 +1200,9 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
/* Free load balancer information string */
free(settings->load_balance_info);
free(settings->wol_mac_addr);
free(settings->wol_broadcast_addr);
/* Free settings structure */
free(settings);

View File

@ -566,6 +566,29 @@ typedef struct guac_rdp_settings {
*/
char* load_balance_info;
/**
* Whether or not to send a magic WoL packet to wake up the host before
* trying to connect. Zero will disable sending the packet, non-zero
* values will trigger sending the packet.
*/
int wol_send_packet;
/**
* The mac address to put in the magic WoL packet.
*/
char* wol_mac_addr;
/**
* The broadcast address to send the magic WoL packet to.
*/
char* wol_broadcast_addr;
/**
* The amount of time to wait after sending the magic WoL packet before
* continuing the connection.
*/
int wol_wait_time;
} guac_rdp_settings;
/**

View File

@ -20,9 +20,11 @@
#include "config.h"
#include "client.h"
#include "common/defaults.h"
#include "settings.h"
#include <guacamole/user.h>
#include <guacamole/wol-constants.h>
#include <stdlib.h>
#include <string.h>
@ -66,6 +68,10 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
"timezone",
"disable-copy",
"disable-paste",
"wol-send-packet",
"wol-mac-addr",
"wol-broadcast-addr",
"wol-wait-time",
NULL
};
@ -288,6 +294,34 @@ enum SSH_ARGS_IDX {
*/
IDX_DISABLE_PASTE,
/**
* Whether the magic WoL packet should be sent prior to starting the
* connection. If set to "true", the system will attempt to send the WoL
* packet and wait for the host to wake up. By default the WoL packet
* is not sent.
*/
IDX_WOL_SEND_PACKET,
/**
* The MAC address to put in the magic WoL packet to wake the remote system.
* By default no MAC address is specified. If WoL is enabled by a MAC
* address is not provided a warning will be logged and the WoL packet will
* not be sent.
*/
IDX_WOL_MAC_ADDR,
/**
* The broadcast address to which to send the magic WoL packet to wake the
* remote system.
*/
IDX_WOL_BROADCAST_ADDR,
/**
* The amount of time to wait after sending the magic WoL packet prior to
* continuing the connection attempt.
*/
IDX_WOL_WAIT_TIME,
SSH_ARGS_COUNT
};
@ -476,6 +510,33 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_DISABLE_PASTE, false);
/* Parse Wake-on-LAN (WoL) parameters. */
settings->wol_send_packet =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_WOL_SEND_PACKET, false);
if (settings->wol_send_packet) {
if (strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) {
guac_user_log(user, GUAC_LOG_WARNING, "WoL was enabled, but no ",
"MAC address was provide. WoL will not be sent.");
settings->wol_send_packet = false;
}
settings->wol_mac_addr =
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_WOL_MAC_ADDR, NULL);
settings->wol_broadcast_addr =
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST);
settings->wol_wait_time =
guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME);
}
/* Parsing was successful */
return settings;
@ -521,6 +582,10 @@ void guac_ssh_settings_free(guac_ssh_settings* settings) {
/* Free the client timezone. */
free(settings->timezone);
/* Free Wake-on-LAN settings. */
free(settings->wol_mac_addr);
free(settings->wol_broadcast_addr);
/* Free overall structure */
free(settings);

View File

@ -287,6 +287,26 @@ typedef struct guac_ssh_settings {
*/
char* timezone;
/**
* Whether or not to send the Wake-on-LAN magic packet.
*/
bool wol_send_packet;
/**
* The MAC address to put in the magic WoL packet for the host to wake.
*/
char* wol_mac_addr;
/**
* The broadcast address to which to send the magic WoL packet.
*/
char* wol_broadcast_addr;
/**
* The amount of time to wait for the system to wake after sending the packet.
*/
int wol_wait_time;
} guac_ssh_settings;
/**

View File

@ -36,6 +36,7 @@
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <guacamole/client.h>
#include <guacamole/wol.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@ -201,6 +202,20 @@ void* ssh_client_thread(void* data) {
pthread_t input_thread;
/* If Wake-on-LAN is enabled, attempt to wake. */
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
}
/* Init SSH base libraries */
if (guac_common_ssh_init(client)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,

View File

@ -19,9 +19,11 @@
#include "config.h"
#include "common/defaults.h"
#include "settings.h"
#include <guacamole/user.h>
#include <guacamole/wol-constants.h>
#include <sys/types.h>
#include <regex.h>
@ -57,6 +59,10 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = {
"login-failure-regex",
"disable-copy",
"disable-paste",
"wol-send-packet",
"wol-mac-addr",
"wol-broadcast-addr",
"wol-wait-time",
NULL
};
@ -232,6 +238,31 @@ enum TELNET_ARGS_IDX {
*/
IDX_DISABLE_PASTE,
/**
* Whether to send the magic Wake-on-LAN (WoL) packet. If set to "true"
* the WoL packet will be sent prior to attempting to connect to the remote
* host. By default the WoL packet will not be sent.
*/
IDX_WOL_SEND_PACKET,
/**
* The MAC address to put in the magic WoL packet to wake the remote host.
* There is no default value, and if WoL is enabled but the MAC address
* is not provided, a warning will be logged and no packet will be sent.
*/
IDX_WOL_MAC_ADDR,
/**
* The broadcast address to which to send the magic WoL packet.
*/
IDX_WOL_BROADCAST_ADDR,
/**
* The amount of time, in seconds, to wait after the magic WoL packet is
* sent before continuing the connection attempt.
*/
IDX_WOL_WAIT_TIME,
TELNET_ARGS_COUNT
};
@ -454,6 +485,37 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user,
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_DISABLE_PASTE, false);
/* Parse Wake-on-LAN (WoL) settings */
settings->wol_send_packet =
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_WOL_SEND_PACKET, false);
if (settings->wol_send_packet) {
/* If WoL has been enabled but no MAC provided, log warning and disable. */
if(strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) {
guac_user_log(user, GUAC_LOG_WARNING, "Wake on LAN was requested, ",
"but no MAC address was specified. WoL will not be sent.");
settings->wol_send_packet = false;
}
/* Parse the WoL MAC address. */
settings->wol_mac_addr =
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_WOL_MAC_ADDR, NULL);
/* Parse the WoL broadcast address. */
settings->wol_broadcast_addr =
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST);
/* Parse the WoL wait time. */
settings->wol_wait_time =
guac_user_parse_args_int(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME);
}
/* Parsing was successful */
return settings;

View File

@ -257,6 +257,30 @@ typedef struct guac_telnet_settings {
*/
char* terminal_type;
/**
* Whether or not to send the magic Wake-on-LAN (WoL) packet prior to
* continuing the connection.
*/
bool wol_send_packet;
/**
* The MAC address to put in the magic WoL packet for the remote host to
* wake.
*/
char* wol_mac_addr;
/**
* The broadcast address to which to send the magic WoL packet to wake
* the remote host.
*/
char* wol_broadcast_addr;
/**
* The number of seconds to wait after sending the magic WoL packet before
* continuing the connection.
*/
int wol_wait_time;
} guac_telnet_settings;
/**

View File

@ -26,6 +26,7 @@
#include <guacamole/client.h>
#include <guacamole/protocol.h>
#include <guacamole/wol.h>
#include <libtelnet.h>
#include <errno.h>
@ -557,6 +558,20 @@ void* guac_telnet_client_thread(void* data) {
char buffer[8192];
int wait_result;
/* If Wake-on-LAN is enabled, attempt to wake. */
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
}
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
telnet_client->recording = guac_common_recording_create(client,

View File

@ -20,9 +20,11 @@
#include "config.h"
#include "client.h"
#include "common/defaults.h"
#include "settings.h"
#include <guacamole/user.h>
#include <guacamole/wol-constants.h>
#include <stdbool.h>
#include <stdlib.h>
@ -82,6 +84,11 @@ const char* GUAC_VNC_CLIENT_ARGS[] = {
"create-recording-path",
"disable-copy",
"disable-paste",
"wol-send-packet",
"wol-mac-addr",
"wol-broadcast-addr",
"wol-wait-time",
NULL
};
@ -333,6 +340,31 @@ enum VNC_ARGS_IDX {
*/
IDX_DISABLE_PASTE,
/**
* Whether to send the magic Wake-on-LAN (WoL) packet to wake the remote
* host prior to attempting to connect. If set to "true" the packet will
* be sent. By default the packet will not be sent.
*/
IDX_WOL_SEND_PACKET,
/**
* The MAC address to place in the magic WoL packet to wake the remote host.
* If WoL is requested but this is not provided a warning will be logged
* and the WoL packet will not be sent.
*/
IDX_WOL_MAC_ADDR,
/**
* The broadcast packet to which to send the magic WoL packet.
*/
IDX_WOL_BROADCAST_ADDR,
/**
* The number of seconds to wait after sending the magic WoL packet before
* attempting to connect to the remote host.
*/
IDX_WOL_WAIT_TIME,
VNC_ARGS_COUNT
};
@ -550,6 +582,37 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user,
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_DISABLE_PASTE, false);
/* Parse Wake-on-LAN (WoL) settings */
settings->wol_send_packet =
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_WOL_SEND_PACKET, false);
if (settings->wol_send_packet) {
/* If WoL has been enabled but no MAC provided, log warning and disable. */
if(strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) {
guac_user_log(user, GUAC_LOG_WARNING, "Wake on LAN was requested, ",
"but no MAC address was specified. WoL will not be sent.");
settings->wol_send_packet = false;
}
/* Parse the WoL MAC address. */
settings->wol_mac_addr =
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_WOL_MAC_ADDR, NULL);
/* Parse the WoL broadcast address. */
settings->wol_broadcast_addr =
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST);
/* Parse the WoL wait time. */
settings->wol_wait_time =
guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME);
}
return settings;
}

View File

@ -270,6 +270,31 @@ typedef struct guac_vnc_settings {
*/
bool recording_include_keys;
/**
* Whether or not to send the magic Wake-on-LAN (WoL) packet prior to
* trying to connect to the remote host. By default this will not be sent.
* If this option is enabled but a MAC address is not provided a warning will
* be logged and the packet will not be sent.
*/
bool wol_send_packet;
/**
* The MAC address to place in the magic WoL packet to wake the remote host.
*/
char* wol_mac_addr;
/**
* The broadcast address to which to send the magic WoL packet to wake
* the remote host.
*/
char* wol_broadcast_addr;
/**
* The number of seconds after sending the magic WoL packet to wait before
* attempting to connect to the remote host.
*/
int wol_wait_time;
} guac_vnc_settings;
/**

View File

@ -46,6 +46,7 @@
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
#include <guacamole/wol.h>
#include <rfb/rfbclient.h>
#include <rfb/rfbproto.h>
@ -238,6 +239,20 @@ void* guac_vnc_client_thread(void* data) {
guac_vnc_client* vnc_client = (guac_vnc_client*) client->data;
guac_vnc_settings* settings = vnc_client->settings;
/* If Wake-on-LAN is enabled, attempt to wake. */
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
}
/* Configure clipboard encoding */
if (guac_vnc_set_clipboard_encoding(client, settings->clipboard_encoding)) {
guac_client_log(client, GUAC_LOG_INFO, "Using non-standard VNC "