--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/ipsec/ipsec6/src/sc_sap.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,170 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// sc_sap.cpp - IPv6/IPv4 IPSEC security policy service access point
+//
+
+#include <ip6_hook.h>
+#include "ipsec.h"
+#include "sc.h"
+#include "ipseclog.h"
+
+//
+CProviderSecpol::CProviderSecpol(MSecurityPolicyManager& aProtocol) : iProtocol(aProtocol)
+ /**
+ * Constructor.
+ *
+ * @param aProtocol The SECPOL protocol object reference
+ */
+ {
+ }
+
+// Required Pure virtual methods
+// *****************************
+void CProviderSecpol::Start()
+ {
+ iListening = 1; // For now, always set. If application does not
+ // read the socket, then one packet is queued and
+ // the rest dropped (iQueueLimit <= 0).
+ }
+
+
+// CProviderSecpol::Write
+// **********************
+TUint CProviderSecpol::Write(const TDesC8 &aDesc, TUint /*aOptions*/, TSockAddr* /*aAddr=NULL*/)
+ /**
+ * Create a new security policy from the policy definition.
+ *
+ * The policy manager application uses this datagram socket API to load the IPsec policy.
+ * Each write (datagram) represents a complete policy and it totally replaces any previously
+ * loaded policy.
+ *
+ * The definition string must entirely be in this one buffer, and if the policy definition
+ * is long, then arranging this may require changing the socket send buffer size
+ * (#KSOSendBuf option).
+ *
+ * @param aDesc The new policy (currently as UNICODE string)
+ * @param options Not used
+ * @param anAddr Not used.
+ * @return 1 (always)
+ *
+ * If there are any syntax errors or problems with parsing the policy information, write
+ * generates a "fake" IPv4 packet (source and destination are 0.0.0.0) containing the
+ * failed line as a payload.
+ *
+ * This packed is then given to the Deliver method of the policy protocol instance
+ * where it is handled like any other dropped packets. The source port of the information
+ * block contains the error code.
+ */
+ {
+ TInt result = KErrNone;
+
+ if (!iSocket)
+ return 1;
+
+ for (;;) // JUST TO PROVIDE NICE "BREAK"-EXITS FOR ERRORS!
+ {
+ TUint offset = 0;
+#if defined(_UNICODE)
+ // This assumes the policy socket on UNICODE is written with *WIDE* characters.
+ TPtrC ptr((TUint16 *)aDesc.Ptr(), aDesc.Length() / 2);
+#else
+ TPtrC ptr(aDesc);
+#endif
+ if ((result = iProtocol.SetPolicy(ptr, offset)) == KErrNone)
+ {
+ return 1; // The successful policy load exit!
+ }
+
+ // Failure to parse the policy specification
+ //
+ // Try to extract the line where error occurred and pass
+ // this information to someone. Currently, construct a
+ // a fake IP packet with the piece of erroneous policy
+ // file as a content (speed is of no concern here)
+ //
+ // (A quick kludge, some more elegant error reporting
+ // might be designed later... -- msa)
+ //
+ TInt start = offset;
+ TInt end = offset;
+ while (start > 0)
+ {
+ if (ptr[start-1] == '\r' || ptr[start-1] == '\n')
+ break;
+ --start;
+ }
+ while (++end < ptr.Length())
+ if (ptr[end] == '\r' || ptr[end] == '\n')
+ break;
+#ifdef _LOG
+ const TPtrC tmp(ptr.Mid(start, end-start));
+ Log::Printf(_L("Policy syntax error: %S"), &tmp);
+#endif
+#if defined(_UNICODE)
+ TPtrC8 line((TUint8 *)(ptr.Ptr() + start), (end - start - 1) * 2);
+#else
+ TPtrC8 line(ptr.Ptr() + start, end - start - 1);
+#endif
+ RMBufRecvPacket packet;
+ RMBufRecvInfo* info = NULL;
+ TRAPD(err, info = packet.CreateL(line, TInet6HeaderIP4::MinHeaderLength()));
+ err = err; // Clearing "never used" warning caused by TRAPD
+ if(info)
+ {
+ //
+ // Setup "fake" IPv4 header
+ //
+ packet.Align(TInet6HeaderIP4::MinHeaderLength());
+ TInet6HeaderIP4 *ip = (TInet6HeaderIP4 *)packet.First()->Ptr();
+ ip->Init();
+ ip->SetTotalLength(info->iLength);
+ ip->SetDstAddr(0);
+ ip->SetSrcAddr(0);
+ info->iSrcAddr.SetPort(result);
+ info->iDstAddr.SetPort(offset - start);
+ iProtocol.Deliver(packet); // Deliver takes "unpacked" packets...
+ }
+ packet.Free(); // Deliver only makes copies, must release it self!
+ //
+ // ALWAYS BREAK, to terminate the "fake" loop construct!
+ //
+ break;
+ }
+
+ // Pass the error to socket server
+ //
+ // Apparently this is not enough for datagram. This does not cause the application
+ // Send request to get error status! Something more complex is required... -- msa
+ //
+ iSocket->Error(result, MSocketNotify::EErrorSend);
+ //
+ // As long as SECPOL socket is "message based", this must always return 1
+ // (no blocking occurs).
+ return 1;
+ }
+
+TBool CProviderSecpol::IsReceiving()
+ /**
+ * @return TRUE, if socket can accept dropped packets.
+ */
+ {
+ if (iQueueLimit < 0 || !iListening)
+ {
+ // Receive Queue limit is full, cannot receive this packet
+ iPacketsDropped++;
+ return FALSE;
+ }
+ return TRUE;
+ }
+