Software

The VirtualBox Guest Additions are software services which allow client operating systems to interact with the Virtualisation environment, breaking the limitation of strictly running the client OS on emulated hardware. Facilities provided include cut and paste between the Client OS and the host system, much better display support with resizing, and even drag and drop of files (which I have not got working).

Up until about Ubuntu 14.04, the method for installing the VirtualBox Guest Additions was to install Ubuntu and then to (virtually) install the Guest Additions CD image provided by VirtualBox and run the installation from that. This no longer works under Ubuntu 17.10 (and I read that it didn’t work for Ubuntu 16, but I can’t verify that). Instead, packages are provided in Ubuntu itself to support the VirtualBox virtualisation facilities.

Based on a video by ‘Linux Video Tutorials’, here are the steps to install the VirtualBox Guest Additions in Ubuntu 17.10:

Settings for VirtualBox VM

    • set plenty of Video Memory (128Mb) in Display->Screen
    • set 3D Acceleration active in Display->Screen
    • enable PAE/NX under System->Processor
    • enable the bidirectional clipboard and drag and drop if you want them, in General->Advanced.

Installing the software

% sudo apt-get update
% sudo apt-get upgrade
% sudo apt-get install build-essential virtualbox-guest-dkms virtualbox-guest-x11
% sudo shutdown -r now

Checking that the software is working

The client OS should now boot with flexible display resizing and cut and paste support. The VirtualBox Guest Additions services should be enabled and running. I found I had to start them:

% hostnamectl
% sudo systemctl status virtualbox-guest-utils.service
% sudo systemctl start virtualbox-guest-utils.service
% sudo systemctl status virtualbox-guest-utils.service

% ps -ef | grep -i vbox
 root 280 2 0 11:36 ? 00:00:00 [iprt-VBoxWQueue]
 lemon 1501 1 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --clipboard
 lemon 1504 1501 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --clipboard
 lemon 1505 1 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --display
 lemon 1506 1505 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --display
 lemon 1512 1 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --seamless
 lemon 1513 1512 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --seamless
 lemon 1519 1 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --draganddrop
 lemon 1520 1519 0 11:37 ? 00:00:00 /usr/bin/VBoxClient --draganddrop
 root 20751 1 0 11:40 ? 00:00:00 /usr/sbin/VBoxService

I’ve been trying to use Ruby libraries to access Sharepoint and am having trouble getting to the starting line.  NTLM authentication from Ruby doesn’t seem to be in a good state.  I’m using httpi-0.9.6 as my HTTP library, which by default uses httpclient-2.2.4, and for NTLM support I’m using httpi-ntlm-0.9.6.  All this is running under Ruby 1.8.7 which incorporates Net::NTLM 0.1.1 which http-ntlm relies on.

In my enterprise environment, I need to use NTLM authentication to access the Sharepoint server.  So, I format the username string supplied to httpi as “USERDOMAIN\username”.  It happens that the Sharepoint machine I want to access is in a different NTLM domain than the user account that I want to access it with.  When httpclient does the NTLM authentication phase, it uses facilities from Net::NTLM to format a Type 1 Message.  This is where the problems start.  Firstly, httpclient doesn’t do the right (undocumented) things necessary to get Net::NTLM to properly include the user’s domain into the request.

case state
  when :init
    t1 = Net::NTLM::Message::Type1.new
    t1.domain = domain if domain
    return t1.encode64
end

The trouble here is that this code doesn’t properly tell Net::NTLM that this domain information should be incorporated into the request.  As written, HTTPI generates a corrupt request, as can be seen from a Wireshark trace.  It’s additionally necessary to enable the resulting SecurityBuffer and to set a flag in the request indicating that the domain is being signalled:

case state
  when :init
    t1 = Net::NTLM::Message::Type1.new
    if domain
      t1.domain = domain
      t1.enable(:domain)
      t1.set_flag(:DOMAIN_SUPPLIED)
    end
    return t1.encode64

But when you do this, you find that the packet is still corrupt, because the offset to the domain name data in the resulting request is incorrect.  This is because of what appears to be a bug in Net::NTLM.  That’s not so easy to fix and play about with, because it’s incorporated into Ruby itself.  The problem is that the offsets are calculated by adding the sizes of the SecurityBuffers defined for the message type, regardless of whether a particular SecurityBuffer is active or not. For my testing purposes, I forced the additional “workstation” SecurityBuffer to be active (with an arbitrary non-null value) in the same way as the Domain, and by doing so, was able to generate a valid request.

But imagine my horror when my requests were still denied by the server.  Further investigation revealed that Net::NTLM ignores the user-specified domain when generating the subsequent Type 3 Message, substituting instead the Target value returned in the Challenge of the Type 2 Message.

Further hackery will be required to fix that, but another approach might be to use Curb instead of httpclient.