[Openswan Users] Connection against a Lucent FW success!!!! but may be there's still room for improvement
Rolando Zappacosta
zappacor at yahoo.com.ar
Sun Apr 5 13:36:54 EDT 2009
Hi all,
I could finally manage to get OSW to work against a Lucen VPN Gateway even through NAT. So, in case someone else needs such connection, compile below code and then run this:
modprobe ip_queue
UDP501encap &
iptables -A OUTPUT -d 135.244.223.254 -j QUEUE
iptables -A INPUT -s 135.244.223.254 -j QUEUE
before launching OSW as usual.
Paul,
is there a way to add this short&simple piece of code into OSW? I heard other commercial products do this same thing (changing the UDP to other than 501 though, but this could be done user-configurable).
The code is:
RJZ-LNX UDP501 # cat UDP501encap.c
/*
* This code is GPL.
*/
/*
To compile:
gcc UDP501encap.c -o UDP501encap -lipq
*/
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 2048
#define BOOL int
#define DstPort 501
#define DstPortHi DstPort >> 8
#define DstPortLo DstPort & 0x00FF
#define SrcPort 501
#define SrcPortHi SrcPort >> 8
#define SrcPortLo SrcPort & 0x00FF
typedef unsigned short u16;
typedef unsigned long u32;
u16 ip_sum_calc(u16 len_ip_header, unsigned char buff[])
{
u16 word16;
u32 sum=0;
u16 i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for (i=0;i<len_ip_header;i=i+2){
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
sum = sum + (u32) word16;
}
// take only 16 bits out of the 32 bit sum and add up the carries
while (sum>>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// one's complement the result
sum = ~sum;
return ((u16) sum);
}
static void die(struct ipq_handle *h)
{
ipq_perror("passer");
ipq_destroy_handle(h);
exit(1);
}
int main(int argc, char **argv)
{
int status;
unsigned char buf[BUFSIZE];
struct ipq_handle *h;
unsigned char *newPayload;
u16 srcaddr[4], dstaddr[4];
u16 newCS;
int ip_header_len;
u16 udp_len;
int i;
h = ipq_create_handle(0, PF_INET);
if (!h)
die(h);
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0)
die(h);
do {
status = ipq_read(h, buf, BUFSIZE, 0);
if (status < 0)
die(h);
switch (ipq_message_type(buf))
{
case NLMSG_ERROR:
fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(buf));
break;
case IPQM_PACKET:
{
ipq_packet_msg_t *m = ipq_get_packet(buf);
//Enable this to debug the incoming/outgoing packets:
//printf("0x%02x %s -> %s (%d)\n", m->payload[9], m->indev_name, m->outdev_name, m->data_len);
if(m->outdev_name[0] == 0x0)
{
// INPUT
ip_header_len = (m->payload[0] & 0xF) * 4;
u16 new_ip_len = m->data_len - ip_header_len - 8;
newPayload = malloc(new_ip_len);
memcpy(newPayload, m->payload + ip_header_len + 8, new_ip_len);
status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
free(newPayload);
}
else
{
u16 ip_len = (m->payload[2] << 8 & 0xff00) + (m->payload[3] & 0xff);
ip_header_len = (m->payload[0] & 0xF) * 4;
u16 new_ip_len = ip_len + ip_header_len + 8;
newPayload = malloc(new_ip_len);
// Copy prev packet
char *dst = newPayload;
char *org = m->payload;
// Copy IP header
memcpy(dst, org, ip_header_len);
dst += ip_header_len;
// Update IP length field
newPayload[2] = new_ip_len >> 8;
newPayload[3] = new_ip_len & 0x00ff;
// Set IP protocol field to UDP
newPayload[9] = 0x11;
// Calculate and update IP cksum
newPayload[10] = newPayload[11] = 0x00;
newCS = ip_sum_calc(ip_header_len, newPayload);
newPayload[10] = newCS >> 8;
newPayload[11] = newCS & 0x00FF;
// Create UDP header
dst[0] = SrcPortHi; // src port
dst[1] = SrcPortLo; // src port
dst[2] = DstPortHi; // dst port
dst[3] = DstPortLo; // dst port
u16 new_udp_len = new_ip_len - ip_header_len;
dst[4] = new_udp_len >> 8; // total len
dst[5] = new_udp_len & 0x00ff; // total len
dst[6] = 0x00; // Cksum
dst[7] = 0x00; // Cksum
dst += 8;
// Clone the rest of the packet
memcpy(dst, org, ip_len);
status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
free(newPayload);
}
if (status < 0)
die(h);
break;
}
default:
fprintf(stderr, "Unknown message type!\n");
break;
}
} while (1);
ipq_destroy_handle(h);
return 0;
}
RJZ-LNX UDP501 #
--- On Wed, 9/10/08, Paul Wouters <paul at xelerance.com> wrote:
> From: Paul Wouters <paul at xelerance.com>
> Subject: Re: [Openswan Users] Connection against a Lucent FW success!!!! but may be there's still room for improvement
> To: "Rolando J. Zappacosta" <zappacor at yahoo.com.ar>
> Cc: users at openswan.org
> Date: Wednesday, September 10, 2008, 6:39 AM
> On Tue, 9 Sep 2008, Rolando J. Zappacosta wrote:
>
> > > If you have the logs from the lucent side, to see
> what vendorid is logged
> > > on their side, I'd be interested so we can
> add it to our own recognised
> > > vendor list (and possible take action based on
> it)
> > I discussed this subject here:
> >
> http://lists.openswan.org/pipermail/users/2008-February/014030.html
> based on
> > what I could capture under Windows, the relevant part
> of it is:
> > "I'm trying to connect OpenSwan to a Lucent
> VPN Gateway, which according to
> > its ASCII interpretation of its Vendor ID payload is:
> >
> 4C5647392E312E3235353A425249434B3A392E312E323535="LVG9.1.255:BRICK:9.1.255".
> I
> > can connect to it by means of the Lucent VPN Client
> V7.1.2 on a Windows XP
> > computer (Vendor ID=
> 4C5643372E312E323A5850="LVC7.1.2:XP")."
>
> Thanks. Normally vendorids are md5sum's of some text,
> though in this case
> that does not seem to be the case. I added them as-is to
> vendor.c for now.
>
> > Seems one can know the running version of the client
> and server just looking
> > on the vendor id part of an ASCII capture dump.
> > Interesting thing is, as explained to you privatelly,
> the way the PSK gets
> > handled here. Under the LVC (windows) I had to
> configure a PSK like:
> > <MyCompanysPSK> where the real PSK is 9 ASCII
> characters long. However, I
> > could find that in order to have OSW establishing
> phase 1 succesfully I had to
> > add the string "01234567890" as a trailer,
> i.e. my ipsec.secrets looks like:
> > !@#$% <MyCompanysGWipAddress> : PSK
> "<MyCompanysPSK>01234567890"
> >
> > what gives a PSK of lenght 20. Not sure on how they
> handle it but my guess is
> > they just take the PSK the user configures, add the
> string
> > "01234567890123456789" and take the first 20
> bytes of it. Easy way to hook you
> > on their client while still keeping it simply to
> develop.
> >
> > And I'm not sure if the user !@#$% is the one the
> GW admin configured on it or
> > if it's the way they handle it but whatever else I
> configure, the GW just
> > don't respond anything back to me.
>
> Thanks! I put a note of this in docs/lucent-client.txt, and
> it will end up
> in the new wiki once we have it online.
>
> > > Looks like a resend, you can ignore it.
> > Strangely, I *always* do receive the duplicate packet
> warning. Another
> > interesting thing is Lucent's VPN client
> doesn't exchange any CFG at all...
> > I'm wondering now if I need it indeed. The server
> sends it to me but seems
> > like OSW only configures the local IP address based on
> it. I supossed it was
> > going to be able to configure something else, such as
> DNS or things like that.
>
> Openswan does support DNS/WINS via XAUTH/ModeConfig. Though
> as a client, we
> might be ignoring it, since we have no structured way of
> modifying resolv.conf
> in any modern way (eg dbus/networkmanager). I believe we
> might only pass it
> as env variables to the updown script.
>
> > The LVC do more things with no CFG at all, configures
> the DNS and WINS servers
> > for instance, something I'll need to do manually
> via a script (or can it be
> > made automatically somehow by OSW?)
>
> You can copy the stock _updown script and add resolv.conf
> rewriting to it,
> and configure the new script using leftupdown=
>
> > > > and this one from pluto's debug:
> > > > 3) "Intranet" #1: XAUTH:
> Unsupported attribute: INTERNAL_ADDRESS_EXPIRY
> > > You can also ignore this. Openswan does not
> support INTERNAL_ADDRESS_EXPIRY,
> > > so it wont drop the IP address or ask for a new
> one.
> > Same for "ignoring informational payload, type
> IPSEC_RESPONDER_LIFETIME"
> > above?
>
> Yes. the remote is telling us how long they will keep the
> SA around. Openswan
> does not really care what the remote does. If the remote
> wants to rekey, it
> will and can do it anytime. We do enforce our own SA life
> similarly.
>
> Paul
More information about the Users
mailing list