(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 System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Runtime.InteropServices;
using System.Security.Principal;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
@ -1749,6 +1752,9 @@ namespace IEC61850
public class ClientConnection : IDisposable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientConnection_getSecurityToken(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientConnection_getPeerAddress(IntPtr self);
@ -1772,6 +1778,31 @@ namespace IEC61850
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()
{
lock (this)
@ -2611,6 +2642,29 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
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>
/// callback handler to control client read access to data attributes
/// 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));
}
private void InternalSVCBEventHandlerImplementation(IntPtr svcb, int eventType, IntPtr parameter)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
@ -3177,6 +3230,38 @@ namespace IEC61850
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);
private ReadAccessHandler readAccessHandler = null;

@ -17,6 +17,7 @@ using IEC61850.Client;
using ReportControlBlock = IEC61850.Server.ReportControlBlock;
using IEC61850.Model;
using System.Data.Common;
using IEC61850;
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)*/
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");
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.
* 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_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);
if (iedServer.IsRunning())

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

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

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

Loading…
Cancel
Save