diff --git a/agents/radagent_it_test.go b/agents/radagent_it_test.go index 806efb3ec..727ace527 100644 --- a/agents/radagent_it_test.go +++ b/agents/radagent_it_test.go @@ -22,10 +22,10 @@ along with this program. If not, see package agents import ( + "bytes" "fmt" "os/exec" "path" - "reflect" "testing" "time" @@ -54,6 +54,7 @@ var ( testRAitTPFromFolder, testRAitAuthPAPSuccess, testRAitAuthPAPFail, + testRAitMandatoryFail, testRAitAuthCHAPSuccess, testRAitAuthCHAPFail, testRAitAuthMSCHAPV2Success, @@ -90,13 +91,14 @@ func TestRAit(t *testing.T) { } func TestRAitDispatcher(t *testing.T) { + engine.KillEngine(100) if *encoding == utils.MetaGOB { t.SkipNow() return } isDispatcherActive = true - engine.StartEngine(path.Join(*dataDir, "conf", "samples", "dispatchers", "all"), 200) - engine.StartEngine(path.Join(*dataDir, "conf", "samples", "dispatchers", "all2"), 200) + engine.StartEngine(path.Join(*dataDir, "conf", "samples", "dispatchers", "all"), 400) + engine.StartEngine(path.Join(*dataDir, "conf", "samples", "dispatchers", "all2"), 400) raonfigDIR = "dispatchers/radagent" testRadiusitResetAllDB(t) for _, stest := range sTestsRadius { @@ -238,7 +240,7 @@ func testRAitAuthPAPSuccess(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", utils.ToJSON(reply.AVPs)) - } else if !reflect.DeepEqual([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { + } else if !bytes.Equal([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -283,11 +285,39 @@ func testRAitAuthPAPFail(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", reply.AVPs) - } else if !reflect.DeepEqual(utils.RadauthFailed, string(reply.AVPs[0].RawValue)) { + } else if utils.RadauthFailed != string(reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } +func testRAitMandatoryFail(t *testing.T) { + if raAuthClnt, err = radigo.NewClient("udp", "127.0.0.1:1812", "CGRateS.org", dictRad, 1, nil); err != nil { + t.Fatal(err) + } + authReq := raAuthClnt.NewRequest(radigo.AccessRequest, 1) // emulates Kamailio packet out of radius_load_caller_avps() + if err := authReq.AddAVPWithName("User-Name", "10011", ""); err != nil { + t.Error(err) + } + if err := authReq.AddAVPWithName("User-Password", "CGRateSPassword3", ""); err != nil { + t.Error(err) + } + // encode the password as required so we can decode it properly + authReq.AVPs[1].RawValue = radigo.EncodeUserPassword([]byte("CGRateSPassword3"), []byte("CGRateS.org"), authReq.Authenticator[:]) + reply, err := raAuthClnt.SendRequest(authReq) + if err != nil { + t.Fatal(err) + } + if reply.Code != radigo.AccessReject { + t.Errorf("Received reply: %+v", reply) + } + exp := "ATTRIBUTES_ERROR:" + utils.MandatoryIEMissingCaps + ": [RadReplyMessage]" + if len(reply.AVPs) != 1 { // make sure max duration is received + t.Errorf("Received AVPs: %+v", reply.AVPs) + } else if exp != string(reply.AVPs[0].RawValue) { + t.Errorf("Expected <%+v>, Received: <%+v>", exp, string(reply.AVPs[0].RawValue)) + } +} + func testRAitAuthCHAPSuccess(t *testing.T) { if raAuthClnt, err = radigo.NewClient("udp", "127.0.0.1:1812", "CGRateS.org", dictRad, 1, nil); err != nil { t.Fatal(err) @@ -327,7 +357,7 @@ func testRAitAuthCHAPSuccess(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", utils.ToJSON(reply.AVPs)) - } else if !reflect.DeepEqual([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { + } else if !bytes.Equal([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -371,7 +401,7 @@ func testRAitAuthCHAPFail(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", reply.AVPs) - } else if !reflect.DeepEqual(utils.RadauthFailed, string(reply.AVPs[0].RawValue)) { + } else if utils.RadauthFailed != string(reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -432,7 +462,7 @@ func testRAitAuthMSCHAPV2Success(t *testing.T) { if avp.Number == 26 && len(avp.RawValue) != 49 { t.Errorf("Unexpected lenght of MS-CHAP2-Success AVP: %+v", len(avp.RawValue)) } - if avp.Number == 225 && !reflect.DeepEqual([]byte("session_max_time#10800"), reply.AVPs[1].RawValue) { + if avp.Number == 225 && !bytes.Equal([]byte("session_max_time#10800"), reply.AVPs[1].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -490,7 +520,7 @@ func testRAitAuthMSCHAPV2Fail(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", reply.AVPs) - } else if !reflect.DeepEqual(utils.RadauthFailed, string(reply.AVPs[0].RawValue)) { + } else if utils.RadauthFailed != string(reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -530,7 +560,7 @@ func testRAitChallenge(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure the client receive the message t.Errorf("Received AVPs: %+v", utils.ToJSON(reply.AVPs)) - } else if !reflect.DeepEqual([]byte("Missing User-Password"), reply.AVPs[0].RawValue) { + } else if !bytes.Equal([]byte("Missing User-Password"), reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } @@ -575,7 +605,7 @@ func testRAitChallengeResponse(t *testing.T) { } if len(reply.AVPs) != 1 { // make sure max duration is received t.Errorf("Received AVPs: %+v", utils.ToJSON(reply.AVPs)) - } else if !reflect.DeepEqual([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { + } else if !bytes.Equal([]byte("session_max_time#10800"), reply.AVPs[0].RawValue) { t.Errorf("Received: %s", string(reply.AVPs[0].RawValue)) } } diff --git a/data/conf/samples/dispatchers/radagent/authchap.json b/data/conf/samples/dispatchers/radagent/authchap.json index 39193305d..4f0e338cf 100644 --- a/data/conf/samples/dispatchers/radagent/authchap.json +++ b/data/conf/samples/dispatchers/radagent/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage", "mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/conf/samples/radagent_internal/authchap.json b/data/conf/samples/radagent_internal/authchap.json index 39193305d..4f0e338cf 100644 --- a/data/conf/samples/radagent_internal/authchap.json +++ b/data/conf/samples/radagent_internal/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage", "mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/conf/samples/radagent_internal_gob/authchap.json b/data/conf/samples/radagent_internal_gob/authchap.json index 39193305d..51a6e79ff 100644 --- a/data/conf/samples/radagent_internal_gob/authchap.json +++ b/data/conf/samples/radagent_internal_gob/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage","mandatory":true}, + ], + }, ], - } -} \ No newline at end of file + }, +}, \ No newline at end of file diff --git a/data/conf/samples/radagent_mongo/authchap.json b/data/conf/samples/radagent_mongo/authchap.json index 39193305d..02bc00a4a 100644 --- a/data/conf/samples/radagent_mongo/authchap.json +++ b/data/conf/samples/radagent_mongo/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage","mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/conf/samples/radagent_mongo_gob/authchap.json b/data/conf/samples/radagent_mongo_gob/authchap.json index 39193305d..02bc00a4a 100644 --- a/data/conf/samples/radagent_mongo_gob/authchap.json +++ b/data/conf/samples/radagent_mongo_gob/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage","mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/conf/samples/radagent_mysql/authchap.json b/data/conf/samples/radagent_mysql/authchap.json index 39193305d..02bc00a4a 100644 --- a/data/conf/samples/radagent_mysql/authchap.json +++ b/data/conf/samples/radagent_mysql/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage","mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/conf/samples/radagent_mysql_gob/authchap.json b/data/conf/samples/radagent_mysql_gob/authchap.json index 39193305d..02bc00a4a 100644 --- a/data/conf/samples/radagent_mysql_gob/authchap.json +++ b/data/conf/samples/radagent_mysql_gob/authchap.json @@ -46,6 +46,27 @@ "type": "*variable", "value": "~*cgrep.Error"} ] }, + { + "id": "RadiusMandatoryFail", + "filters": ["*string:~*vars.*radReqType:*radAuth","*string:~*req.User-Name:10011"], + "flags": ["*log", "*authorize", "*attributes"], + "request_fields":[ + {"tag": "UserName", "path": "*cgreq.RadUserName", "type": "*variable", + "value": "~*req.User-Name"}, + {"tag": "Password", "path": "*cgreq.RadPassword", "type": "*variable", + "value": "~*req.User-Password"}, + {"tag": "ReplyMessage", "path": "*cgreq.RadReplyMessage", "type": "*constant", + "value": "*attributes"}, + ], + "reply_fields":[ + {"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], + "type": "*constant", "value": "AccessReject"}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message","filters": ["*notempty:~*cgrep.Error:"], + "type": "*variable", "value": "~*cgrep.Error", "blocker":true}, + {"tag": "ReplyMessage", "path": "*rep.Reply-Message", + "type": "*variable", "value": "~*cgrep.Attributes.RadReplyMessage","mandatory":true}, + ], + }, ], } } \ No newline at end of file diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index 284a00ece..89df28d63 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -26,4 +26,5 @@ cgrates.org,ATTR_API_RATES_AUTH,*auth,*string:~*req.ApiKey:rPrf12345,,,*req.APIM cgrates.org,ATTR_API_CORE_AUTH,*auth,*string:~*req.ApiKey:core12345,,,*req.APIMethods,*constant,CoreSv1.Status&CoreSv1.Ping&CoreSv1.Sleep&CoreSv1.StartCPUProfiling&CoreSv1.StopCPUProfiling&CoreSv1.StartMemoryProfiling&CoreSv1.StopMemoryProfiling,false,20 cgrates.org,ATTR_API_ACTIONS_AUTH,*auth,*string:~*req.ApiKey:actPrf12345,,,*req.APIMethods,*constant,ActionSv1.Ping,false,20 cgrates.org,ATTR_API_ACCOUNTS_AUTH,*auth,*string:~*req.ApiKey:accPrf12345,,,*req.APIMethods,*constant,AccountSv1.Ping,false,20 -cgrates.org,ATTR_API_EES_AUTH,*auth,*string:~*req.ApiKey:ees12345,,,*req.APIMethods,*constant,EeSv1.Ping&EeSv1.ProcessEvent,false,20 \ No newline at end of file +cgrates.org,ATTR_API_EES_AUTH,*auth,*string:~*req.ApiKey:ees12345,,,*req.APIMethods,*constant,EeSv1.Ping&EeSv1.ProcessEvent,false,20 +cgrates.org,ATTR_RAD,*any,*string:~*req.RadUserName:10011;*string:~*req.RadPassword:CGRateSPassword3,,,,,,false,10 \ No newline at end of file diff --git a/data/tariffplans/oldtutorial/Attributes.csv b/data/tariffplans/oldtutorial/Attributes.csv index 30513b14f..46f105f2a 100644 --- a/data/tariffplans/oldtutorial/Attributes.csv +++ b/data/tariffplans/oldtutorial/Attributes.csv @@ -3,4 +3,5 @@ cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:0 cgrates.org,ATTR_1,,,,,*req.Account,*constant,1001,, cgrates.org,ATTR_1,,,,,*req.Subject,*constant,1001,, -cgrates.org,ATTR_PASS,*sessions,*string:~*req.Account:1001,,,*req.PasswordFromAttributes,*constant,CGRateSPassword1,false,10 \ No newline at end of file +cgrates.org,ATTR_PASS,*sessions,*string:~*req.Account:1001,,,*req.PasswordFromAttributes,*constant,CGRateSPassword1,false,10 +cgrates.org,ATTR_RAD,*any,*string:~*req.RadUserName:10011;*string:~*req.RadPassword:CGRateSPassword3,,,,,,false,10 \ No newline at end of file