Skip to content

Commit

Permalink
Added support for *stir_initiate
Browse files Browse the repository at this point in the history
  • Loading branch information
Trial97 authored and danbogos committed Apr 16, 2020
1 parent 0fadf12 commit 3e8d182
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 21 deletions.
5 changes: 4 additions & 1 deletion config/config_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,11 @@ const CGRATES_CFG_JSON = `
"terminate_attempts": 5, // attempts to get the session before terminating it
"alterable_fields": [], // the session fields that can be updated
//"min_dur_low_balance": "5s", // threshold which will trigger low balance warnings for prepaid calls (needs to be lower than debit_interval)
"stir_attest": "*any", // the default attest for stir/shaken authentification <*any|A|B|C>
"stir_allowed_attest": ["*any"], // the default attest for stir/shaken authentication <*any|A|B|C>
"stir_payload_maxduration": "-1", // the duration that stir header is valid after it was created
"stir_default_attest": "A", // the default attest level if not mentioned in API
"stir_publickey_path": "", // the path to the public key
"stir_privatekey_path": "", // the path to the private key
},
Expand Down
5 changes: 4 additions & 1 deletion config/config_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,8 +694,11 @@ func TestSmgJsonCfg(t *testing.T) {
Channel_sync_interval: utils.StringPointer("0"),
Terminate_attempts: utils.IntPointer(5),
Alterable_fields: &[]string{},
Stir_attest: utils.StringPointer(utils.META_ANY),
Stir_allowed_attest: &[]string{utils.META_ANY},
Stir_payload_maxduration: utils.StringPointer("-1"),
Stir_default_attest: utils.StringPointer("A"),
Stir_privatekey_path: utils.StringPointer(""),
Stir_publickey_path: utils.StringPointer(""),
}
if cfg, err := dfCgrJsonCfg.SessionSJsonCfg(); err != nil {
t.Error(err)
Expand Down
3 changes: 2 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,9 @@ func TestCgrCfgJSONDefaultsSMGenericCfg(t *testing.T) {
ChannelSyncInterval: 0,
TerminateAttempts: 5,
AlterableFields: utils.NewStringSet([]string{}),
STIRAttest: utils.NewStringSet([]string{utils.META_ANY}),
STIRAllowedAttest: utils.NewStringSet([]string{utils.META_ANY}),
STIRPayloadMaxduration: -1,
STIRDefaultAttest: "A",
}
if !reflect.DeepEqual(eSessionSCfg, cgrCfg.sessionSCfg) {
t.Errorf("expecting: %s, received: %s",
Expand Down
5 changes: 4 additions & 1 deletion config/libconfig_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,11 @@ type SessionSJsonCfg struct {
Terminate_attempts *int
Alterable_fields *[]string
Min_dur_low_balance *string
Stir_attest *string
Stir_allowed_attest *[]string
Stir_payload_maxduration *string
Stir_default_attest *string
Stir_publickey_path *string
Stir_privatekey_path *string
}

// FreeSWITCHAgent config section
Expand Down
20 changes: 16 additions & 4 deletions config/sessionscfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,11 @@ type SessionSCfg struct {
TerminateAttempts int
AlterableFields *utils.StringSet
MinDurLowBalance time.Duration
STIRAttest *utils.StringSet
STIRAllowedAttest *utils.StringSet
STIRPayloadMaxduration time.Duration
STIRDefaultAttest string
STIRPublicKeyPath string
STIRPrivateKeyPath string
}

func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
Expand Down Expand Up @@ -277,14 +280,23 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
return err
}
}
if jsnCfg.Stir_attest != nil {
scfg.STIRAttest = utils.NewStringSet(strings.Split(*jsnCfg.Stir_attest, utils.NestingSep))
if jsnCfg.Stir_allowed_attest != nil {
scfg.STIRAllowedAttest = utils.NewStringSet(*jsnCfg.Stir_allowed_attest)
}
if jsnCfg.Stir_payload_maxduration != nil {
if scfg.STIRPayloadMaxduration, err = utils.ParseDurationWithNanosecs(*jsnCfg.Stir_payload_maxduration); err != nil {
return err
}
}
if jsnCfg.Stir_default_attest != nil {
scfg.STIRDefaultAttest = *jsnCfg.Stir_default_attest
}
if jsnCfg.Stir_publickey_path != nil {
scfg.STIRPublicKeyPath = *jsnCfg.Stir_publickey_path
}
if jsnCfg.Stir_privatekey_path != nil {
scfg.STIRPrivateKeyPath = *jsnCfg.Stir_privatekey_path
}
return nil
}

Expand Down Expand Up @@ -316,7 +328,7 @@ func (scfg *SessionSCfg) AsMapInterface() map[string]interface{} {
utils.TerminateAttemptsCfg: scfg.TerminateAttempts,
utils.AlterableFieldsCfg: scfg.AlterableFields.AsSlice(),
utils.MinDurLowBalanceCfg: scfg.MinDurLowBalance,
utils.STIRAtestCfg: strings.Join(scfg.STIRAttest.AsSlice(), utils.NestingSep),
utils.STIRAtestCfg: strings.Join(scfg.STIRAllowedAttest.AsSlice(), utils.NestingSep),
utils.STIRPayloadMaxdurationCfg: scfg.STIRPayloadMaxduration,
}
}
Expand Down
44 changes: 37 additions & 7 deletions general_tests/session2_it_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ var (
testSes2ItLoadFromFolder,
testSes2ItInitSession,
testSes2ItAsActiveSessions,
testSes2StirAuthorize,
testSes2StirAuthenticate,
testSes2StirInit,
testSes2ItStopCgrEngine,
}
)
Expand Down Expand Up @@ -181,9 +182,9 @@ func testSes2ItStopCgrEngine(t *testing.T) {
}
}

func testSes2StirAuthorize(t *testing.T) {
func testSes2StirAuthenticate(t *testing.T) {
args := &sessions.V1ProcessEventArgs{
Flags: []string{"*stir_authorize"},
Flags: []string{utils.MetaSTIRAuthenticate},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testSes2StirAuthorize",
Expand All @@ -207,14 +208,43 @@ func testSes2StirAuthorize(t *testing.T) {
// altered originator
args.CGREvent.Event[utils.STIROriginatorTn] = "1005"
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err == nil || err.Error() != "*stir_authorize: wrong originatorTn" {
t.Errorf("Expected error :%q ,receved: %v", "*stir_authorize: wrong originatorTn", err)
args, &rply); err == nil || err.Error() != "*stir_authenticate: wrong originatorTn" {
t.Errorf("Expected error :%q ,receved: %v", "*stir_authenticate: wrong originatorTn", err)
}

// altered identity
args.CGREvent.Event[utils.STIRIdentity] = "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiL3Vzci9zaGFyZS9jZ3JhdGVzL3N0aXIvc3Rpcl9wdWJrZXkucGVtIn0.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMzg4MDIsIm9yaWciOnsidG4iOiIxMDA1In0sIm9yaWdpZCI6IjEyMzQ1NiJ9.cMEMlFnfyTu8uxfeU4RoZTamA7ifFT9Ibwrvi1_LKwL2xAU6fZ_CSIxKbtyOpNhM_sV03x7CfA_v0T4sHkifzg;info=</usr/share/cgrates/stir/stir_pubkey.pem>;ppt=shaken"
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err == nil || err.Error() != "*stir_authorize: crypto/ecdsa: verification error" {
t.Errorf("Expected error :%q ,receved: %v", "*stir_authorize: crypto/ecdsa: verification error", err)
args, &rply); err == nil || err.Error() != "*stir_authenticate: crypto/ecdsa: verification error" {
t.Errorf("Expected error :%q ,receved: %v", "*stir_authenticate: crypto/ecdsa: verification error", err)
}
}

func testSes2StirInit(t *testing.T) {
args := &sessions.V1ProcessEventArgs{
Flags: []string{utils.MetaSTIRInitiate},
CGREvent: &utils.CGREvent{
Tenant: "cgrates.org",
ID: "testSes2StirInit",
Event: map[string]interface{}{
utils.ToR: utils.VOICE,
utils.OriginID: "testSes2StirInit",
utils.RequestType: utils.META_PREPAID,
utils.Account: "1001",
utils.Subject: "ANY2CNT",
utils.Destination: "1002",
utils.Usage: 10 * time.Minute,
utils.STIRPublicKeyPath: "/usr/share/cgrates/stir/stir_pubkey.pem",
utils.STIRPrivateKeyPath: "/usr/share/cgrates/stir/stir_privatekey.pem",
},
},
}
var rply sessions.V1ProcessEventReply
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
args, &rply); err != nil { // no error verificated with success
t.Error(err)
}
if err := sessions.AuthStirShaken(rply.STIRIdentity, "1001", "", "1002", "", utils.NewStringSet([]string{"A"}), 10*time.Minute); err != nil {
t.Fatal(err)
}
}
3 changes: 2 additions & 1 deletion packages/debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
* [AgentS] Add ability to inject data in cache from agents
* [Config] Config cache format change to include partitions
* [ERs] Add *none EventReader type
* [SessionS] Added support for *stir_authorize
* [SessionS] Added support for *stir_authenticate
* [SessionS] Added support for *stir_initiate

-- Alexandru Tripon <[email protected]> Wed, 19 Feb 2020 13:25:52 +0200

Expand Down
33 changes: 31 additions & 2 deletions sessions/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2874,6 +2874,7 @@ type V1ProcessEventReply struct {
Suppliers *engine.SortedSuppliers
ThresholdIDs *[]string
StatQueueIDs *[]string
STIRIdentity string
}

// AsNavigableMap is part of engine.NavigableMapper interface
Expand Down Expand Up @@ -2956,8 +2957,8 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
if argsFlagsWithParams, err = utils.FlagsWithParamsFromSlice(args.Flags); err != nil {
return
}
if argsFlagsWithParams.HasKey(utils.MetaSTIRAuthorize) {
attest := sS.cgrCfg.SessionSCfg().STIRAttest
if argsFlagsWithParams.HasKey(utils.MetaSTIRAuthenticate) {
attest := sS.cgrCfg.SessionSCfg().STIRAllowedAttest
if uattest := ev.GetStringIgnoreErrors(utils.STIRATest); uattest != utils.EmptyString {
attest = utils.NewStringSet(strings.Split(uattest, utils.INFIELD_SEP))
}
Expand All @@ -2973,6 +2974,34 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
attest, stirMaxDur); err != nil {
return utils.NewSTIRError(err.Error())
}
} else if argsFlagsWithParams.HasKey(utils.MetaSTIRInitiate) {
attest := sS.cgrCfg.SessionSCfg().STIRDefaultAttest
if uattest := ev.GetStringIgnoreErrors(utils.STIRATest); uattest != utils.EmptyString {
attest = uattest
}

destURI := ev.GetStringIgnoreErrors(utils.STIRDestinationTn)
destTn := utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIRDestinationTn), ev.GetStringIgnoreErrors(utils.Destination))

dest := utils.NewPASSporTDestinationsIdentity(strings.Split(destTn, utils.INFIELD_SEP), strings.Split(destURI, utils.INFIELD_SEP))

var orig *utils.PASSporTOriginsIdentity
if origURI := ev.GetStringIgnoreErrors(utils.STIROriginatorURI); origURI != utils.EmptyString {
orig = utils.NewPASSporTOriginsIdentity(utils.EmptyString, origURI)
} else {
orig = utils.NewPASSporTOriginsIdentity(
utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIROriginatorTn),
ev.GetStringIgnoreErrors(utils.Account)),
utils.EmptyString)
}
pubkeyPath := utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIRPublicKeyPath), sS.cgrCfg.SessionSCfg().STIRPublicKeyPath)
prvkeyPath := utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIRPrivateKeyPath), sS.cgrCfg.SessionSCfg().STIRPrivateKeyPath)

payload := utils.NewPASSporTPayload(attest, args.CGREvent.ID, *dest, *orig)
header := utils.NewPASSporTHeader(pubkeyPath)
if rply.STIRIdentity, err = NewIdentity(header, payload, prvkeyPath, sS.cgrCfg.GeneralCfg().ReplyTimeout); err != nil {
return utils.NewSTIRError(err.Error())
}
}
// check for *attribute
if argsFlagsWithParams.HasKey(utils.MetaAttributes) {
Expand Down
5 changes: 4 additions & 1 deletion utils/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,8 @@ const (
MetaRelease = "*release"
MetaAllocate = "*allocate"
MetaAuthorize = "*authorize"
MetaSTIRAuthorize = "*stir_authorize"
MetaSTIRAuthenticate = "*stir_authenticate"
MetaSTIRInitiate = "*stir_initiate"
MetaInit = "*init"
MetaRatingPlanCost = "*rating_plan_cost"
RatingPlanIDs = "RatingPlanIDs"
Expand Down Expand Up @@ -1985,6 +1986,8 @@ const (
STIROriginatorURI = "STIROriginatorURI"
STIRDestinationTn = "STIRDestinationTn"
STIRDestinationURI = "STIRDestinationURI"
STIRPublicKeyPath = "STIRPublicKeyPath"
STIRPrivateKeyPath = "STIRPrivateKeyPath"

STIRExtraInfoPrefix = ";info=<"
STIRExtraInfoSuffix = ">;alg=ES256;ppt=shaken"
Expand Down
2 changes: 1 addition & 1 deletion utils/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,5 +264,5 @@ func ErrNotConvertibleTF(from, to string) error {

// NewSTIRError returns a error with a *stir_authorize prefix
func NewSTIRError(reason string) error {
return fmt.Errorf("%s: %s", MetaSTIRAuthorize, reason)
return fmt.Errorf("%s: %s", MetaSTIRAuthenticate, reason)
}
2 changes: 1 addition & 1 deletion utils/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func TestNewErrChargerS(t *testing.T) {
}

func TestNewSTIRError(t *testing.T) {
expected := `*stir_authorize: wrong header`
expected := `*stir_authenticate: wrong header`
if rcv := NewSTIRError("wrong header"); rcv.Error() != expected {
t.Errorf("Expecting: %q, received: %q", expected, rcv.Error())
}
Expand Down

0 comments on commit 3e8d182

Please sign in to comment.