- MMS server: ACSE authenticator passes application reference (ap-title and ae-qualifier)

This commit is contained in:
Michael Zillgith 2017-10-19 15:09:17 +02:00
parent 34dff85ed6
commit d8f964ac7c
7 changed files with 98 additions and 48 deletions

View file

@ -37,13 +37,34 @@ void sigint_handler(int signalId)
static char* password1 = "user1@testpw";
static char* password2 = "user2@testpw";
static void printAppTitle(ItuObjectIdentifier* oid)
{
int i;
for (i = 0; i < oid->arcCount; i++) {
printf("%i", oid->arc[i]);
if (i != (oid->arcCount - 1))
printf(".");
}
printf("\n");
}
/**
* This is the AcseAuthenticator callback function that is invoked on each client connection attempt.
* When returning true the server stack accepts the client. Otherwise the connection is rejected.
*
* The security token can be used to pass an application specific object to other library callbacks
*/
static bool
clientAuthenticator(void* parameter, AcseAuthenticationParameter authParameter, void** securityToken)
clientAuthenticator(void* parameter, AcseAuthenticationParameter authParameter, void** securityToken, IsoApplicationReference* appRef)
{
printf("ACSE Authenticator:\n");
printf(" client ap-title: "); printAppTitle(&(appRef->apTitle)); printf("\n");
printf(" client ae-qualifier: %i\n", appRef->aeQualifier);
if (authParameter->mechanism == ACSE_AUTH_PASSWORD) {
if (authParameter->value.password.passwordLength == strlen(password1)) {
if (memcmp(authParameter->value.password.octetString, password1,

View file

@ -89,39 +89,6 @@ BerDecoder_decodeUint32(uint8_t* buffer, int intLen, int bufPos)
return value;
}
#if 0
int32_t
BerDecoder_decodeInt32(uint8_t* buffer, int intlen, int bufPos)
{
int32_t value = 0;
bool isNegative = ((buffer[bufPos] & 0x80) == 0x80);
int i = 0;
if (isNegative) {
for (i = 0; i < 4; i++) {
value <<= 8;
if (i < (4 - intlen))
value += 0xff;
else
value += buffer[bufPos + i - (4 - intlen)];
}
}
else {
for (i = 0; i < intlen; i++) {
value <<= 8;
value += buffer[bufPos + i];
}
}
return value;
}
#endif
#if 1
int32_t
BerDecoder_decodeInt32(uint8_t* buffer, int intlen, int bufPos)
{
@ -142,7 +109,6 @@ BerDecoder_decodeInt32(uint8_t* buffer, int intlen, int bufPos)
return value;
}
#endif
float
BerDecoder_decodeFloat(uint8_t* buffer, int bufPos)
@ -197,3 +163,38 @@ BerDecoder_decodeBoolean(uint8_t* buffer, int bufPos) {
else
return false;
}
void
BerDecoder_decodeOID(uint8_t* buffer, int bufPos, int length, ItuObjectIdentifier* oid)
{
int startPos = bufPos;
int currentArc = 0;
/* clear all arcs */
int i;
for (i = 0; i < 10; i++)
oid->arc[i] = 0;
/* parse first two arcs */
if (length > 0) {
oid->arc[0] = buffer[bufPos] / 40;
oid->arc[1] = buffer[bufPos] % 40;
currentArc = 2;
bufPos++;
}
/* parse remaining arcs */
while ((bufPos - startPos < length) && (currentArc < 10)) {
oid->arc[currentArc] = oid->arc[currentArc]<<7;
if (buffer[bufPos] < 0x80)
oid->arc[currentArc++] += buffer[bufPos];
else
oid->arc[currentArc] += (buffer[bufPos] & 0x7f);
bufPos++;
}
oid->arcCount = currentArc;
}

View file

@ -48,16 +48,6 @@ typedef enum
} AcseAuthenticationMechanism;
/* --> for compatibility with older versions (libiec61850 < 0.7.7) */
#ifndef AUTH_NONE
#define AUTH_NONE ACSE_AUTH_NONE
#endif
#ifndef AUTH_PASSWORD
#define AUTH_PASSWORD ACSE_AUTH_PASSWORD
#endif
/* <-- for compatibility with older versions (libiec61850 < 0.7.7) */
typedef struct sAcseAuthenticationParameter* AcseAuthenticationParameter;
struct sAcseAuthenticationParameter
@ -99,11 +89,12 @@ AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char*
* \param parameter user provided parameter - set when user registers the authenticator
* \param authParameter the authentication parameters provided by the client
* \param securityToken pointer where to store an application specific security token - can be ignored if not used.
* \param appReference ISO application reference (ap-title + ae-qualifier)
*
* \return true if client connection is accepted, false otherwise
*/
typedef bool
(*AcseAuthenticator)(void* parameter, AcseAuthenticationParameter authParameter, void** securityToken);
(*AcseAuthenticator)(void* parameter, AcseAuthenticationParameter authParameter, void** securityToken, IsoApplicationReference* appReference);
/**
* \brief COTP T selector

View file

@ -155,6 +155,17 @@ typedef struct
typedef struct sMmsNamedVariableList* MmsNamedVariableList;
typedef struct sMmsAccessSpecifier* MmsNamedVariableListEntry;
typedef struct {
uint16_t arc[10];
int arcCount;
} ItuObjectIdentifier;
typedef struct {
ItuObjectIdentifier apTitle;
int aeQualifier;
} IsoApplicationReference;
/**@}*/

View file

@ -54,6 +54,7 @@ typedef struct sAcseConnection
int userDataBufferSize;
AcseAuthenticationParameter authentication;
AcseAuthenticator authenticator;
IsoApplicationReference applicationReference;
void* authenticatorParameter;
void* securityToken;
} AcseConnection;

View file

@ -46,4 +46,7 @@ BerDecoder_decodeDouble(uint8_t* buffer, int bufPos);
bool
BerDecoder_decodeBoolean(uint8_t* buffer, int bufPos);
void
BerDecoder_decodeOID(uint8_t* buffer, int bufPos, int length, ItuObjectIdentifier* oid);
#endif /* BER_DECODER_H_ */

View file

@ -69,7 +69,10 @@ authenticateClient(AcseConnection* self, AcseAuthenticationMechanism mechanism,
authParameter->value.password.passwordLength = authValueLen;
}
return self->authenticator(self->authenticatorParameter, authParameter, &(self->securityToken));
//TODO Check if we are in a TLS connection: if mechanism == ACSE_AUTH_NONE provide client certificate if present
// --> mechanism = ACSE_AUTH_TLS
return self->authenticator(self->authenticatorParameter, authParameter, &(self->securityToken), &(self->applicationReference));
}
static bool
@ -241,10 +244,28 @@ parseAarqPdu(AcseConnection* self, uint8_t* buffer, int bufPos, int maxBufPos)
break;
case 0xa6: /* calling AP title */
bufPos += len;
{
if (buffer[bufPos] == 0x06) { /* ap-title-form2 */
int innerLength = buffer[bufPos+1];
if (innerLength == len - 2)
BerDecoder_decodeOID(buffer, bufPos + 2, innerLength, &(self->applicationReference.apTitle));
}
}
bufPos += len;
break;
case 0xa7: /* calling AE qualifier */
{
if (buffer[bufPos] == 0x02) { /* ae-qualifier-form2 */
int innerLength = buffer[bufPos+1];
if (innerLength == len - 2)
self->applicationReference.aeQualifier = BerDecoder_decodeInt32(buffer + 2, buffer[bufPos+1], bufPos);
}
}
bufPos += len;
break;
@ -315,6 +336,7 @@ AcseConnection_init(AcseConnection* self, AcseAuthenticator authenticator, void*
self->userDataBufferSize = 0;
self->authenticator= authenticator;
self->authenticatorParameter = parameter;
memset(&(self->applicationReference), 0, sizeof(self->applicationReference));
}
void