- MMS server: ACSE authenticator passes application reference (ap-title and ae-qualifier)
This commit is contained in:
parent
34dff85ed6
commit
d8f964ac7c
7 changed files with 98 additions and 48 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct sAcseConnection
|
|||
int userDataBufferSize;
|
||||
AcseAuthenticationParameter authentication;
|
||||
AcseAuthenticator authenticator;
|
||||
IsoApplicationReference applicationReference;
|
||||
void* authenticatorParameter;
|
||||
void* securityToken;
|
||||
} AcseConnection;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue