--- /dev/null
+#
+# Test the "mruby" module
+#
--- /dev/null
+#
+# Input packet
+#
+Packet-Type = Access-Request
+User-Name = "bob"
+User-Password = "secret"
+Called-Station-Id = "aa:bb:cc:dd:ee:ff"
+Framed-IPv6-Prefix = "11:22:33:44:55:66:77:88/128"
+Vendor-Specific.Cisco.AVPair = "cisco=madness"
+Vendor-Specific.3GPP2.DNS-Server.Primary-IP-Address = 8.8.8.8
+Vendor-Specific.Cisco.AVPair = "is=crazy"
+NAS-Port = 5
+
+#
+# Expected answer
+#
+Packet-Type == Access-Accept
--- /dev/null
+mruby.fetch_root
+if (!ok) {
+ test_fail
+}
+
+mruby.fetch_nested
+if (!ok) {
+ test_fail
+}
+
+mruby.set_simple
+if (!ok) {
+ test_fail
+}
+if (NAS-Identifier != 'Test NAS') {
+ test_fail
+}
+
+mruby.overwrite_simple
+if (!ok) {
+ test_fail
+}
+if (User-Name != 'john') {
+ test_fail
+}
+
+mruby.set_nested
+if (!updated) {
+ test_fail
+}
+if (control.Vendor-Specific.Cisco.AVPair != 'very=special') {
+ test_fail
+}
+if (Vendor-Specific.3GPP2.DNS-Server.Secondary-IP-Address != 1.1.1.1) {
+ test_fail
+}
+if (Vendor-Specific.3GPP2.DNS-Server[1].Primary-IP-Address != 10.9.8.7) {
+ test_fail
+}
+if (Vendor-Specific.Cisco.AVPair[2] != 'top=secret') {
+ test_fail
+}
+
+mruby.overwrite_nested
+if (!updated) {
+ test_fail
+}
+if (Vendor-Specific.Cisco.AVPair[1] != 'silly=idea') {
+ test_fail
+}
+if (Vendor-Specific.3GPP2.DNS-Server[1].Primary-IP-Address != 1.2.3.4) {
+ test_fail
+}
+
+mruby.list_pairs
+if (!noop) {
+ test_fail
+}
+
+test_pass
--- /dev/null
+#
+# Input packet
+#
+Packet-Type = Access-Request
+User-Name = "bob"
+User-Password = "secret"
+Called-Station-Id = "aa:bb:cc:dd:ee:ff"
+Framed-IPv6-Prefix = "11:22:33:44:55:66:77:88/128"
+Vendor-Specific.Cisco.AVPair = "cisco=madness"
+Vendor-Specific.3GPP2.DNS-Server.Primary-IP-Address = 8.8.8.8
+Vendor-Specific.Cisco.AVPair = "is=crazy"
+NAS-Port = 5
+
+#
+# Expected answer
+#
+Packet-Type == Access-Accept
--- /dev/null
+mruby.del_from_root
+if (!updated) {
+ test_fail
+}
+if (User-Name) {
+ test_fail
+}
+
+mruby.del_nested
+if (!updated) {
+ test_fail
+}
+if (Vendor-Specific.Cisco.AVPair[#] != 1) {
+ test_fail
+}
+if (Vendor-Specific.Cisco.AVPair != 'is=crazy') {
+ test_fail
+}
+
+mruby.del_missing
+if (!noop) {
+ test_fail
+}
+if (NAS-Identifier) {
+ test_fail
+}
+
+test_pass
--- /dev/null
+#
+# Input packet
+#
+Packet-Type = Access-Request
+User-Name = "bob"
+User-Password = "secret"
+Called-Station-Id = "aa:bb:cc:dd:ee:ff"
+Framed-IPv6-Prefix = "11:22:33:44:55:66:77:88/128"
+Vendor-Specific.Cisco.AVPair = "cisco=madness"
+Vendor-Specific.3GPP2.DNS-Server.Primary-IP-Address = 8.8.8.8
+Vendor-Specific.Cisco.AVPair = "is=crazy"
+NAS-Port = 5
+
+#
+# Expected answer
+#
+Packet-Type == Access-Accept
--- /dev/null
+mruby_invalid.set_simple {
+ fail = 1
+}
+if (!fail) {
+ test_fail
+}
+
+mruby_invalid.set_type {
+ fail = 1
+}
+if (!fail) {
+ test_fail
+}
+
+mruby_invalid.set_nested_1 {
+ fail = 1
+}
+if (!fail) {
+ test_fail
+}
+mruby_invalid.set_nested_2 {
+ fail = 1
+}
+if (!fail) {
+ test_fail
+}
+
+test_pass
--- /dev/null
+module FreeRADIUS
+
+ # Check setting a simple pair instance 1 when none exist
+ def self.set_simple(p)
+ p.request.nas_identifier.set('Test NAS', 1)
+ return RLM_MODULE_OK
+ end
+
+ # Check setting a string against a numeric
+ def self.set_type(p)
+ p.request.nas_port.set('john')
+ return RLM_MODULE_OK
+ end
+
+ # Check setting nested pairs - invalid instance
+ def self.set_nested_1(p)
+ fr.control.vendor_specific.cisco.avpair.set('very=special', 4)
+ return RLM_MODULE_UPDATED
+ end
+ def self.set_nested_2(p)
+ fr.request.vendor_specific('3GPP2').dns_server(3).primary_ip_address.set('10.9.8.7')
+ return RLM_MODULE_UPDATED
+ end
+
+end
--- /dev/null
+mruby {
+ filename = "src/tests/modules/mruby/test.rb"
+ module = "FreeRADIUS"
+}
+
+mruby mruby_invalid {
+ filename = "src/tests/modules/mruby/invalid.rb"
+ module = "FreeRADIUS"
+}
+
--- /dev/null
+module FreeRADIUS
+
+ # Check access to simple pairs in the root of the list
+ def self.fetch_root(p)
+ if p.request.user_name.get != 'bob' then return RLM_MODULE_FAIL end
+ if p.request.user_name.get(1) != nil then
+ log(L_WARN, p.request.user_name.get(2))
+ return RLM_MODULE_FAIL
+ end
+ return RLM_MODULE_OK
+ end
+
+ # Check access to nested pairs
+ def self.fetch_nested(p)
+ if p.request.vendor_specific.cisco.avpair.get != 'cisco=madness' then return RLM_MODULE_FAIL end
+ if p.request.vendor_specific.cisco.avpair.get(1) != 'is=crazy' then return RLM_MODULE_FAIL end
+ if p.request.vendor_specific('3GPP2').dns_server.primary_ip_address.get != '8.8.8.8' then return RLM_MODULE_FAIL end
+ if p.request.net.src.ip.get != '127.0.0.1' then return RLM_MODULE_FAIL end
+ return RLM_MODULE_OK
+ end
+
+ # Check setting a simple pair
+ def self.set_simple(p)
+ p.request.nas_identifier.set('Test NAS')
+ return RLM_MODULE_OK
+ end
+
+ # Check overwriting an existing simple attribute
+ def self.overwrite_simple(p)
+ p.request.user_name.set('john')
+ return RLM_MODULE_OK
+ end
+
+ # Check setting nested pairs
+ def self.set_nested(p)
+ p.control.vendor_specific.cisco.avpair.set('very=special')
+ p.request.vendor_specific('3GPP2').dns_server.secondary_ip_address.set('1.1.1.1')
+ p.request.vendor_specific('3GPP2').dns_server(1).primary_ip_address.set('10.9.8.7')
+ p.request.vendor_specific.cisco.avpair.set('top=secret', 2)
+ return RLM_MODULE_UPDATED
+ end
+
+ # Check updating an existing nested pair
+ def self.overwrite_nested(p)
+ p.request.vendor_specific.cisco.avpair.set('silly=idea', 1)
+ p.request.vendor_specific('3GPP2').dns_server(1).primary_ip_address.set('1.2.3.4')
+ return RLM_MODULE_UPDATED
+ end
+
+ # Check the keys method works
+ def self.list_pairs(p)
+ p.request.keys.each do |attr|
+ log(L_INFO, attr)
+ end
+ return RLM_MODULE_NOOP
+ end
+
+ # Check deleting a simple attribute from the list root.
+ def self.del_from_root(p)
+ p.request.user_name.del
+ return RLM_MODULE_UPDATED
+ end
+
+ # Check deleting a nested attribute
+ def self.del_nested(p)
+ if p.request.vendor_specific.cisco.avpair.get(1) != 'is=crazy' then return RLM_MODULE_FAIL end
+ p.request.vendor_specific.cisco.avpair.del
+ if p.request.vendor_specific.cisco.avpair.get(1) != nil then return RLM_MODULE_FAIL end
+ return RLM_MODULE_UPDATED
+ end
+
+ # Check deleting a pair that doesn't exist
+ def self.del_missing(p)
+ p.request.nas_identifier.del
+ return RLM_MODULE_NOOP
+ end
+
+end