(LIB61850-513)

-> Add server clientAuthenticator handler;
->Add LIB61850_API AcseAuthenticationParameter_getAuthMechanism;
->iedServer.SetAuthenticator(clientAuthenticator, null) added to server_example_access_control;
v1.6
Maxson Ramon dos Anjos Medeiros 4 weeks ago
parent b22d8ff59f
commit b2631f1b25

@ -0,0 +1,101 @@
/*
* AcseAuthenticationParameter.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
/// <summary>
/// Authentication mechanism used by AcseAuthenticator
/// </summary>
public enum AcseAuthenticationMechanism
{
/** Neither ACSE nor TLS authentication used */
ACSE_AUTH_NONE = 0,
/** Use ACSE password for client authentication */
ACSE_AUTH_PASSWORD = 1,
/** Use ACSE certificate for client authentication */
ACSE_AUTH_CERTIFICATE = 2,
/** Use TLS certificate for client authentication */
ACSE_AUTH_TLS = 3
}
public class AcseAuthenticationParameter
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr AcseAuthenticationParameter_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int AcseAuthenticationParameter_getAuthMechanism(IntPtr self);
private IntPtr self = IntPtr.Zero;
public AcseAuthenticationParameter()
{
self = AcseAuthenticationParameter_create();
}
public AcseAuthenticationParameter(IntPtr self)
{
this.self = self;
}
public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism)
{
AcseAuthenticationParameter_setAuthMechanism(self,(int)acseAuthenticationMechanism);
}
public void SetPassword(string password)
{
AcseAuthenticationParameter_setPassword(self, password);
}
public AcseAuthenticationMechanism GetAuthMechanism()
{
return (AcseAuthenticationMechanism)AcseAuthenticationParameter_getAuthMechanism(self);
}
}
public class IsoApplicationReference
{
private IntPtr self = IntPtr.Zero;
public IsoApplicationReference(IntPtr self)
{
this.self= self;
}
}
}

@ -25,7 +25,10 @@ using IEC61850.Model;
using IEC61850.TLS; using IEC61850.TLS;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal;
// IEC 61850 API for the libiec61850 .NET wrapper library // IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850 namespace IEC61850
@ -1749,6 +1752,9 @@ namespace IEC61850
public class ClientConnection : IDisposable public class ClientConnection : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientConnection_getSecurityToken(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientConnection_getPeerAddress(IntPtr self); static extern IntPtr ClientConnection_getPeerAddress(IntPtr self);
@ -1772,6 +1778,31 @@ namespace IEC61850
this.self = ClientConnection_claimOwnership(self); this.self = ClientConnection_claimOwnership(self);
} }
/// <summary>
/// Get the security token associated with this connection
/// The security token is an opaque handle that is associated with the connection.It is provided by the
/// authenticator (if one is present). If no security token is used then this function returns NULL
/// </summary>
/// <returns>the security token or NULL</returns>
public object GetSecurityToken()
{
lock (this)
{
if (self != IntPtr.Zero)
{
IntPtr token = ClientConnection_getSecurityToken(self);
if (token != IntPtr.Zero)
{
GCHandle handle = GCHandle.FromIntPtr(token);
return handle as object;
}
}
}
return null;
}
public string GetPeerAddress() public string GetPeerAddress()
{ {
lock (this) lock (this)
@ -2611,6 +2642,29 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedServer_SVCBEventHandler(IntPtr svcb, int eventType, IntPtr parameter); private delegate void IedServer_SVCBEventHandler(IntPtr svcb, int eventType, IntPtr parameter);
/// <summary>
/// set the authenticator for this server
/// This function sets a user specified authenticator that is used to identify and authenticate clients that
/// wants to connect.The authenticator is called on each connection attempt.Depending on the return value
/// connections are accepted.
/// </summary>
/// <param name="self">the instance of IedServer to operate on.</param>
/// <param name="authenticator">the user provided authenticator callback</param>
/// <param name="authenticatorParameter">user provided parameter that is passed to the authenticator</param>
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setAuthenticator(IntPtr self, IedServer_AcseAuthenticator authenticator, IntPtr authenticatorParameter);
/// <summary>
/// Callback function to authenticate a client
/// </summary>
/// <param name="parameter">user provided parameter - set when user registers the authenticator</param>
/// <param name="authParameter">the authentication parameters provided by the client</param>
/// <param name="securityToken">pointer where to store an application specific security token - can be ignored if not used.</param>
/// <param name="appReference">ISO application reference (ap-title + ae-qualifier)</param>
/// <returns>true if client connection is accepted, false otherwise</returns>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool IedServer_AcseAuthenticator(IntPtr parameter, IntPtr authParameter, IntPtr securityToken, IntPtr appReference);
/// <summary> /// <summary>
/// callback handler to control client read access to data attributes /// callback handler to control client read access to data attributes
/// User provided callback function to control MMS client read access to IEC 61850 /// User provided callback function to control MMS client read access to IEC 61850
@ -3166,7 +3220,6 @@ namespace IEC61850
IedServer_setSVCBHandler(self, sampledValuesControlBlock.Self, internalSVCBEventHandler, GCHandle.ToIntPtr(info.handle)); IedServer_setSVCBHandler(self, sampledValuesControlBlock.Self, internalSVCBEventHandler, GCHandle.ToIntPtr(info.handle));
} }
private void InternalSVCBEventHandlerImplementation(IntPtr svcb, int eventType, IntPtr parameter) private void InternalSVCBEventHandlerImplementation(IntPtr svcb, int eventType, IntPtr parameter)
{ {
GCHandle handle = GCHandle.FromIntPtr(parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
@ -3177,6 +3230,38 @@ namespace IEC61850
info.sVCBEventHandler(info.sampledValuesControlBlock, (SMVEvent)eventType, info.svcHandlerParameter); info.sVCBEventHandler(info.sampledValuesControlBlock, (SMVEvent)eventType, info.svcHandlerParameter);
} }
//TODO -> Add appReference
public delegate bool AcseAuthenticatorHandler(object parameter, AcseAuthenticationParameter authParameter, object securityToken, IsoApplicationReference isoApplicationReference);
private AcseAuthenticatorHandler acseAuthenticatorHandler = null;
private object acseAuthenticatorHandlerParameter = null;
private IedServer_AcseAuthenticator iedServer_AcseAuthenticator = null;
public void SetAuthenticator(AcseAuthenticatorHandler acseAuthenticatorHandler, object acseAuthenticatorHandlerParameter)
{
this.acseAuthenticatorHandler = acseAuthenticatorHandler;
this.acseAuthenticatorHandlerParameter= acseAuthenticatorHandlerParameter;
if(iedServer_AcseAuthenticator == null)
{
iedServer_AcseAuthenticator = new IedServer_AcseAuthenticator(InternalAcseAuthenticator);
IedServer_setAuthenticator(self, iedServer_AcseAuthenticator, IntPtr.Zero);
}
}
private bool InternalAcseAuthenticator(IntPtr parameter, IntPtr authParameter, IntPtr securityToken, IntPtr appReference)
{
if(acseAuthenticatorHandler != null && authParameter != IntPtr.Zero && appReference != IntPtr.Zero)
{
AcseAuthenticationParameter acseAuthenticationParameter = new AcseAuthenticationParameter(authParameter);
IsoApplicationReference isoApplicationReference = new IsoApplicationReference(appReference);
GCHandle token = GCHandle.FromIntPtr(securityToken);
return acseAuthenticatorHandler(acseAuthenticatorHandlerParameter, acseAuthenticationParameter, token as object, isoApplicationReference);
}
return false;
}
public delegate MmsDataAccessError ReadAccessHandler(LogicalDevice ld, LogicalNode ln, DataObject dataObject, FunctionalConstraint fc, ClientConnection connection, object parameter); public delegate MmsDataAccessError ReadAccessHandler(LogicalDevice ld, LogicalNode ln, DataObject dataObject, FunctionalConstraint fc, ClientConnection connection, object parameter);
private ReadAccessHandler readAccessHandler = null; private ReadAccessHandler readAccessHandler = null;

@ -17,6 +17,7 @@ using IEC61850.Client;
using ReportControlBlock = IEC61850.Server.ReportControlBlock; using ReportControlBlock = IEC61850.Server.ReportControlBlock;
using IEC61850.Model; using IEC61850.Model;
using System.Data.Common; using System.Data.Common;
using IEC61850;
namespace server_access_control namespace server_access_control
{ {
@ -142,12 +143,23 @@ namespace server_access_control
/* Install handler to control access to control blocks (RCBs, LCBs, GoCBs, SVCBs, SGCBs)*/ /* Install handler to control access to control blocks (RCBs, LCBs, GoCBs, SVCBs, SGCBs)*/
bool ControlBlockAccessCallBack(object parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, ControlBlockAccessType accessType) bool ControlBlockAccessCallBack(object parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, ControlBlockAccessType accessType)
{ {
string password = parameter as string;
object securityToken = connection.GetSecurityToken();
if(securityToken != null)
{
if ((securityToken as string == password))
Console.WriteLine("Correct securityToken");
else
Console.WriteLine("Incorrect securityToken");
}
Console.WriteLine(acsiClass.ToString() + " "+ accessType.ToString() + " access " + ld.GetName() + ln.GetName() +"/"+ objectName + "." + subObjectName + "\n"); Console.WriteLine(acsiClass.ToString() + " "+ accessType.ToString() + " access " + ld.GetName() + ln.GetName() +"/"+ objectName + "." + subObjectName + "\n");
return true; return true;
} }
iedServer.SetControlBlockAccessHandler(ControlBlockAccessCallBack, iedServer); iedServer.SetControlBlockAccessHandler(ControlBlockAccessCallBack, "securityToken_password");
/* By default access to variables with FC=DC and FC=CF is not allowed. /* By default access to variables with FC=DC and FC=CF is not allowed.
* This allow to write to simpleIOGenericIO/GGIO1.NamPlt.vendor variable used * This allow to write to simpleIOGenericIO/GGIO1.NamPlt.vendor variable used
@ -332,6 +344,22 @@ namespace server_access_control
iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_1, null); iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_1, null);
iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_2, null); iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_2, null);
bool clientAuthenticator (object parameter, AcseAuthenticationParameter authParameter, object securityToken, IsoApplicationReference isoApplicationReference)
{
Console.WriteLine("ACSE Authenticator:\n");
IEC61850.AcseAuthenticationMechanism acseAuthenticationMechanism = authParameter.GetAuthMechanism();
if (acseAuthenticationMechanism == IEC61850.AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD)
{
}
return false;
}
iedServer.SetAuthenticator(clientAuthenticator, null);
iedServer.Start(102); iedServer.Start(102);
if (iedServer.IsRunning()) if (iedServer.IsRunning())

@ -84,6 +84,8 @@ main(int argc, char** argv)
printf("Failed to connect to %s:%i\n", hostname, tcpPort); printf("Failed to connect to %s:%i\n", hostname, tcpPort);
} }
while (true);
IedConnection_destroy(con); IedConnection_destroy(con);
AcseAuthenticationParameter_destroy(auth); AcseAuthenticationParameter_destroy(auth);

@ -91,6 +91,9 @@ AcseAuthenticationParameter_destroy(AcseAuthenticationParameter self);
LIB61850_API void LIB61850_API void
AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism); AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism);
LIB61850_API AcseAuthenticationMechanism
AcseAuthenticationParameter_getAuthMechanism(AcseAuthenticationParameter self);
LIB61850_API void LIB61850_API void
AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char* password); AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char* password);

@ -63,6 +63,12 @@ AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, A
self->mechanism = mechanism; self->mechanism = mechanism;
} }
AcseAuthenticationMechanism
AcseAuthenticationParameter_getAuthMechanism(AcseAuthenticationParameter self)
{
return self->mechanism;
}
IsoConnectionParameters IsoConnectionParameters
IsoConnectionParameters_create() IsoConnectionParameters_create()
{ {

Loading…
Cancel
Save