mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-30 10:02:53 +00:00
uspot: add advanced captive http components
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"uuid": 2,
|
||||
"radios": [
|
||||
{
|
||||
"band": "6G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "5G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "2G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
}
|
||||
],
|
||||
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "WAN",
|
||||
"role": "upstream",
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"WAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "dynamic"
|
||||
},
|
||||
"ssids": [
|
||||
{
|
||||
"name": "OpenWifi-hotspot",
|
||||
"services": [ "captive" ],
|
||||
"wifi-bands": [
|
||||
"5G",
|
||||
"2G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "psk2",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "optional"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
"services": [ "ssh" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"LAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"subnet": "192.168.1.1/24",
|
||||
"dhcp": {
|
||||
"lease-first": 10,
|
||||
"lease-count": 100,
|
||||
"lease-time": "6h"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"statistics": {
|
||||
"interval": 120,
|
||||
"types": [ "ssids", "lldp", "clients" ]
|
||||
},
|
||||
"health": {
|
||||
"interval": 120
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"ssh": {
|
||||
"port": 22
|
||||
},
|
||||
"captive": {
|
||||
"auth-mode": "click-to-continue",
|
||||
"walled-garden-fqdn": [
|
||||
"*.google.com", "telecominfraproject.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"uuid": 2,
|
||||
"radios": [
|
||||
{
|
||||
"band": "6G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "5G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "2G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
}
|
||||
],
|
||||
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "WAN",
|
||||
"role": "upstream",
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"WAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "dynamic"
|
||||
},
|
||||
"ssids": [
|
||||
{
|
||||
"name": "OpenWifi-hotspot",
|
||||
"services": [ "captive" ],
|
||||
"wifi-bands": [
|
||||
"5G",
|
||||
"2G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "psk2",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "optional"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
"services": [ "ssh" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"LAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"subnet": "192.168.1.1/24",
|
||||
"dhcp": {
|
||||
"lease-first": 10,
|
||||
"lease-count": 100,
|
||||
"lease-time": "6h"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"statistics": {
|
||||
"interval": 120,
|
||||
"types": [ "ssids", "lldp", "clients" ]
|
||||
},
|
||||
"health": {
|
||||
"interval": 120
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"ssh": {
|
||||
"port": 22
|
||||
},
|
||||
"captive": {
|
||||
"auth-mode": "credentials",
|
||||
"credentials": [
|
||||
{
|
||||
"username": "abc",
|
||||
"password": "def"
|
||||
}
|
||||
],
|
||||
"walled-garden-fqdn": [
|
||||
"*.google.com", "telecominfraproject.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"uuid": 2,
|
||||
"radios": [
|
||||
{
|
||||
"band": "6G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "5G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "2G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
}
|
||||
],
|
||||
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "WAN",
|
||||
"role": "upstream",
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"WAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "dynamic"
|
||||
},
|
||||
"ssids": [
|
||||
{
|
||||
"name": "OpenWifi-hotspot",
|
||||
"services": [ "captive" ],
|
||||
"wifi-bands": [
|
||||
"5G",
|
||||
"2G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "psk2",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "optional"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
"services": [ "ssh" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"LAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"subnet": "192.168.1.1/24",
|
||||
"dhcp": {
|
||||
"lease-first": 10,
|
||||
"lease-count": 100,
|
||||
"lease-time": "6h"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"statistics": {
|
||||
"interval": 120,
|
||||
"types": [ "ssids", "lldp", "clients" ]
|
||||
},
|
||||
"health": {
|
||||
"interval": 120
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"ssh": {
|
||||
"port": 22
|
||||
},
|
||||
"captive": {
|
||||
"auth-mode": "radius",
|
||||
"auth-server": "212.24.98.232",
|
||||
"auth-port": 1812,
|
||||
"auth-secret": "secret",
|
||||
"walled-garden-fqdn": [
|
||||
"*.google.com", "telecominfraproject.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"uuid": 2,
|
||||
"radios": [
|
||||
{
|
||||
"band": "6G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "5G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
},
|
||||
{
|
||||
"band": "2G",
|
||||
"country": "CA",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80
|
||||
}
|
||||
],
|
||||
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "WAN",
|
||||
"role": "upstream",
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"WAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "dynamic"
|
||||
},
|
||||
"ssids": [
|
||||
{
|
||||
"name": "OpenWifi-hotspot",
|
||||
"services": [ "captive" ],
|
||||
"wifi-bands": [
|
||||
"5G",
|
||||
"2G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "psk2",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "optional"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
"services": [ "ssh" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"LAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"subnet": "192.168.1.1/24",
|
||||
"dhcp": {
|
||||
"lease-first": 10,
|
||||
"lease-count": 100,
|
||||
"lease-time": "6h"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"statistics": {
|
||||
"interval": 120,
|
||||
"types": [ "ssids", "lldp", "clients" ]
|
||||
},
|
||||
"health": {
|
||||
"interval": 120
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"ssh": {
|
||||
"port": 22
|
||||
},
|
||||
"captive": {
|
||||
"auth-mode": "uam",
|
||||
"uam-port": 3990,
|
||||
"uam-secret": "hotsys123",
|
||||
"uam-server": "https://customer.hotspotsystem.com/customer/hotspotlogin.php",
|
||||
"nasid": "AlmondLabs",
|
||||
"auth-server": "radius.hotspotsystem.com",
|
||||
"auth-port": 1812,
|
||||
"auth-secret": "hotsys123",
|
||||
"walled-garden-fqdn": [
|
||||
"*.google.com", "telecominfraproject.com", "customer.hotspotsystem.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,4 +305,5 @@ VALUE Add-Port-To-IP-Address Yes 1
|
||||
|
||||
#$INCLUDE /etc/radcli/dictionary.microsoft
|
||||
#$INCLUDE /etc/radcli/dictionary.roaringpenguin
|
||||
$INCLUDE /etc/radcli/dictionary.WISPr
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
VENDOR WISPr 14122 WISPr
|
||||
|
||||
ATTRIBUTE WISPr-Location-ID 1 string WISPr
|
||||
ATTRIBUTE WISPr-Location-Name 2 string WISPr
|
||||
ATTRIBUTE WISPr-Logoff-URL 3 string WISPr
|
||||
ATTRIBUTE WISPr-Redirection-URL 4 string WISPr
|
||||
ATTRIBUTE WISPr-Bandwidth-Min-Up 5 integer WISPr
|
||||
ATTRIBUTE WISPr-Bandwidth-Min-Down 6 integer WISPr
|
||||
ATTRIBUTE WISPr-Bandwidth-Max-Up 7 integer WISPr
|
||||
ATTRIBUTE WISPr-Bandwidth-Max-Down 8 integer WISPr
|
||||
ATTRIBUTE WISPr-Session-Terminate-Time 9 string WISPr
|
||||
ATTRIBUTE WISPr-Billing-Class-Of-Service 11 string WISPr
|
||||
26
feeds/ucentral/uspot/Makefile
Normal file
26
feeds/ucentral/uspot/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uspot
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/uspot
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=hotspot daemon
|
||||
DEPENDS:=+spotfilter +uhttpd-mod-ucode +libradcli
|
||||
endef
|
||||
|
||||
define Package/uspot/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin/ $(1)/usr/lib/ucode
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libuam.so $(1)/usr/lib/ucode/uam.so
|
||||
$(CP) ./files/* $(1)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,uspot))
|
||||
36
feeds/ucentral/uspot/files/config
Normal file
36
feeds/ucentral/uspot/files/config
Normal file
@@ -0,0 +1,36 @@
|
||||
ubus call spotfilter interface_add '{ "name": "hotspot", "devices": [ "wlancaptive0", "wlancaptive1" ], "config": { "default_class": 1, "default_dns_class": 0, "class": [ { "index": 0, "device_macaddr": "up0v0", "fwmark": 1,"fwmark_mask": 127}, { "index": 1, "fwmark": 2,"fwmark_mask": 127 }] } }'
|
||||
|
||||
ubus call spotfilter interface_add '{ "name": "hotspot", "devices": [ "wlan0" ], "config": { "class": [ { "index": 0, "device_macaddr": "up0v0", "fwmark": 1,"fwmark_mask": 127}, { "index": 1, "fwmark": 2,"fwmark_mask": 127 }] } }'
|
||||
ubus call spotfilter interface_add '{ "name": "hotspot", "devices": [ "wlan1" ], "config": { "class": [ { "index": 0, "device_macaddr": "up0v0", "fwmark": 1,"fwmark_mask": 127}, { "index": 1, "fwmark": 2,"fwmark_mask": 127 }] } }'
|
||||
|
||||
ubus call spotfilter client_set '{"interface":"hotspot", "address": "1c:57:dc:37:3c:b1", "state": 0, "dns_state": 1}'
|
||||
ubus call spotfilter client_set '{"interface":"hotspot", "address": "e8:a7:30:a0:9c:6e", "state": 0, "dns_state": 1}'
|
||||
ubus call spotfilter client_get '{"interface":"hotspot", "address": "1e:07:4c:c0:89:a7", "state": 0, "dns_state": 1}'
|
||||
|
||||
ubus call spotfilter client_set '{"interface":"hotspot", "address": "e8:a7:30:a0:9c:6e", "state": 0, "dns_state": 1}'
|
||||
ubus call spotfilter client_get '{"interface":"hotspot", "address": "1c:57:dc:37:3c:b1", "state": 0, "dns_state": 1}'
|
||||
|
||||
config redirect
|
||||
option name 'HTTP-Redirect'
|
||||
option src up0v0
|
||||
option src_dport 80
|
||||
option proto tcp
|
||||
option target DNAT
|
||||
option mark 1/127
|
||||
|
||||
|
||||
config rule
|
||||
option name 'Allow-captive-up0v0'
|
||||
option src 'up0v0'
|
||||
option dest_port '80'
|
||||
option proto 'tcp'
|
||||
option mark 2/127
|
||||
option target 'ACCEPT'
|
||||
|
||||
config rule
|
||||
option name 'Allow-captive-up0v0'
|
||||
option src 'up0v0'
|
||||
option dest_port '80'
|
||||
option proto 'tcp'
|
||||
option mark 1/127
|
||||
option target 'ACCEPT'
|
||||
25
feeds/ucentral/uspot/files/etc/config/uspot
Normal file
25
feeds/ucentral/uspot/files/etc/config/uspot
Normal file
@@ -0,0 +1,25 @@
|
||||
config uspot config
|
||||
#option auth_mode 'uam'
|
||||
#option auth_mode 'radius'
|
||||
#option auth_mode 'credentials'
|
||||
option auth_mode 'click-to-continue'
|
||||
|
||||
config radius radius
|
||||
# option auth_server 212.24.98.232
|
||||
# option auth_port 1812
|
||||
# option auth_secret secret
|
||||
|
||||
config uam uam
|
||||
# option port 3990
|
||||
# option nasid AlmondLabs
|
||||
# option nasmac 903cb3bb25e3
|
||||
# option server https://customer.hotspotsystem.com/customer/hotspotlogin.php
|
||||
# option secret hotsys123
|
||||
|
||||
#config credential
|
||||
# option username abc
|
||||
# option password def
|
||||
|
||||
#config credential
|
||||
# option username 123
|
||||
# option password 456
|
||||
8
feeds/ucentral/uspot/files/usr/share/uspot/allow.uc
Normal file
8
feeds/ucentral/uspot/files/usr/share/uspot/allow.uc
Normal file
@@ -0,0 +1,8 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
|
||||
<h1> Connected </h1>
|
||||
|
||||
{{ footer }}
|
||||
11
feeds/ucentral/uspot/files/usr/share/uspot/auth.uc
Normal file
11
feeds/ucentral/uspot/files/usr/share/uspot/auth.uc
Normal file
@@ -0,0 +1,11 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
|
||||
{{ form_data.username }}
|
||||
{{ form_data.password }}
|
||||
|
||||
<h1> Radius auth </h1>
|
||||
|
||||
{{ footer }}
|
||||
19
feeds/ucentral/uspot/files/usr/share/uspot/click.uc
Normal file
19
feeds/ucentral/uspot/files/usr/share/uspot/click.uc
Normal file
@@ -0,0 +1,19 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
{% if (error): %}
|
||||
<h1> {{ PO('accept_terms_error', 'Please accept the terms of use.') }} </h1>
|
||||
{% endif %}
|
||||
<h5 class="card-title">{{ PO('welcome', 'Welcome!') }}</h5>
|
||||
<p class="card-text">{{ PO('accept_terms_header', 'To access the Internet you must Accept the Terms of Service.') }}</p>
|
||||
<hr>
|
||||
<form action="/hotspot" method="post">
|
||||
<input type="hidden" name="action" value="click">
|
||||
<input type="checkbox" name="accept_terms" value="clicked">{{ PO('accept_terms_checkbox', 'I accept the terms of use') }}
|
||||
<input type="submit" value="{{ PO('accept_terms_button', 'Accept Terms of Service') }}" class="btn btn-primary btn-block">
|
||||
{% if (query_string?.redir): %}
|
||||
<input type="hidden" name="redir" value="{{ query_string.redir }}">
|
||||
{% endif %}
|
||||
</form>
|
||||
{{ footer }}
|
||||
8
feeds/ucentral/uspot/files/usr/share/uspot/connected.uc
Normal file
8
feeds/ucentral/uspot/files/usr/share/uspot/connected.uc
Normal file
@@ -0,0 +1,8 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
|
||||
<h1> you are already Connected </h1>
|
||||
|
||||
{{ footer }}
|
||||
14
feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc
Normal file
14
feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc
Normal file
@@ -0,0 +1,14 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="refresh" content="0; URL=http://{{env.SERVER_ADDR}}/hotspot/?redir={{env.headers.host}}" />
|
||||
</head>
|
||||
<body style="background-color: white">
|
||||
<a style="color: black; font-family: arial, helvetica, sans-serif;" href="http://{{env.SERVER_ADDR}}/hotspot">HotSpot Login</a>
|
||||
</body>
|
||||
</html>
|
||||
18
feeds/ucentral/uspot/files/usr/share/uspot/credentials.uc
Normal file
18
feeds/ucentral/uspot/files/usr/share/uspot/credentials.uc
Normal file
@@ -0,0 +1,18 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
{% if (error): %}
|
||||
<h1> Invalid credentials </h1>
|
||||
{% endif %}
|
||||
|
||||
<form action="/hotspot" method="POST">
|
||||
<label for="fname">Username:</label>
|
||||
<input type="text" name="username"><br>
|
||||
<label for="fname">Password:</label>
|
||||
<input type="password" name="password">
|
||||
<input type="hidden" name="action" value="credentials">
|
||||
<input type="submit" value="Login" class="btn btn-primary btn-block">
|
||||
</form>
|
||||
|
||||
{{ footer }}
|
||||
22
feeds/ucentral/uspot/files/usr/share/uspot/dump-env.uc
Normal file
22
feeds/ucentral/uspot/files/usr/share/uspot/dump-env.uc
Normal file
@@ -0,0 +1,22 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
<h1>Headers</h1>
|
||||
|
||||
{% for (let k, v in env.headers): %}
|
||||
<strong>{{ replace(k, /(^|-)(.)/g, (m0, d, c) => d + uc(c)) }}</strong>: {{ v }}<br>
|
||||
{% endfor %}
|
||||
|
||||
<h1>Environment</h1>
|
||||
|
||||
{% for (let k, v in env): if (type(v) == 'string'): %}
|
||||
<code>{{ k }}={{ v }}</code><br>
|
||||
{% endif; endfor %}
|
||||
|
||||
{% if (env.CONTENT_LENGTH > 0): %}
|
||||
<h1>Body Contents</h1>
|
||||
|
||||
{% for (let chunk = uhttpd.recv(64); chunk != null; chunk = uhttpd.recv(64)): %}
|
||||
<code>{{ replace(chunk, /[^[:graph:]]/g, '.') }}</code><br>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
8
feeds/ucentral/uspot/files/usr/share/uspot/error.uc
Normal file
8
feeds/ucentral/uspot/files/usr/share/uspot/error.uc
Normal file
@@ -0,0 +1,8 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
|
||||
<h1> An Error occured, please try again </h1>
|
||||
|
||||
{{ footer }}
|
||||
9
feeds/ucentral/uspot/files/usr/share/uspot/footer
Normal file
9
feeds/ucentral/uspot/files/usr/share/uspot/footer
Normal file
@@ -0,0 +1,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
{%
|
||||
|
||||
'use strict';
|
||||
|
||||
global.handle_request = function(env) {
|
||||
include('cpd.uc', { env });
|
||||
};
|
||||
%}
|
||||
@@ -0,0 +1,7 @@
|
||||
{%
|
||||
|
||||
'use strict';
|
||||
|
||||
global.handle_request = function(env) {
|
||||
include("dump-env.uc", { env });
|
||||
};
|
||||
93
feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc
Normal file
93
feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc
Normal file
@@ -0,0 +1,93 @@
|
||||
{%
|
||||
|
||||
'use strict';
|
||||
|
||||
let fs = require('fs');
|
||||
let rtnl = require('rtnl');
|
||||
|
||||
let file = fs.open('/usr/share/uspot/header', 'r');
|
||||
let header = file.read('all');
|
||||
file.close();
|
||||
|
||||
file = fs.open('/usr/share/uspot/footer', 'r');
|
||||
let footer = file.read('all');
|
||||
file.close();
|
||||
|
||||
let uci = require('uci').cursor();
|
||||
let config = uci.get_all('uspot');
|
||||
|
||||
let uam = require('uam');
|
||||
|
||||
// give a client access to the internet
|
||||
function allow_client(ctx) {
|
||||
system('ubus call spotfilter client_set \'{ "interface": "hotspot", "address": "' + replace(ctx.mac, '-', ':') + '", "state": 1, "dns_state": 1}\'');
|
||||
include('allow.uc', ctx);
|
||||
}
|
||||
|
||||
// log the client in via radius
|
||||
function auth_client(ctx) {
|
||||
if (!ctx.query_string.username || !ctx.query_string.password) {
|
||||
include('allow.uc', ctx);
|
||||
return false;
|
||||
}
|
||||
let password = uam.password(uam.md5(config.uam.challenge, ctx.mac), ctx.query_string.password, config.uam.uam_secret);
|
||||
|
||||
let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w');
|
||||
cfg.write({
|
||||
type: 'uam-auth',
|
||||
server: sprintf('%s:%s:%s',config.radius.auth_server, config.radius.auth_port, config.radius.auth_secret),
|
||||
username: ctx.mac,
|
||||
password,
|
||||
acct_session: "0123456789",
|
||||
client_ip: ctx.env.REMOTE_ADDR,
|
||||
called_station: ctx.mac,
|
||||
calling_station: config.uam.nasmac,
|
||||
nas_ip: ctx.env.SERVER_ADDR,
|
||||
nas_id: config.uam.nasid
|
||||
});
|
||||
cfg.close();
|
||||
|
||||
let stdout = fs.popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json');
|
||||
let reply;
|
||||
if (!stdout) {
|
||||
request_start({ ...ctx, error: 1 });
|
||||
return;
|
||||
}
|
||||
reply = json(stdout.read('all'));
|
||||
stdout.close();
|
||||
if (reply['access-accept']) {
|
||||
allow_client(ctx);
|
||||
return;
|
||||
}
|
||||
include('error.uc', ctx);
|
||||
}
|
||||
|
||||
global.handle_request = function(env) {
|
||||
let mac;
|
||||
let form_data = {};
|
||||
let query_string = {};
|
||||
let post_data = '';
|
||||
let ctx = { env, header, footer, mac, form_data, post_data, query_string, config };
|
||||
|
||||
// lookup the peers MAC
|
||||
let macs = rtnl.request(rtnl.const.RTM_GETNEIGH, rtnl.const.NLM_F_DUMP, { });
|
||||
for (let m in macs)
|
||||
if (m.dst == env.REMOTE_HOST)
|
||||
ctx.mac = replace(m.lladdr, ':', '-');
|
||||
|
||||
// if the MAC lookup failed, go to the error page
|
||||
if (!ctx.mac)
|
||||
include('error.uc', ctx);
|
||||
|
||||
// split QUERY_STRING
|
||||
if (env.QUERY_STRING)
|
||||
for (let chunk in split(env.QUERY_STRING, '&')) {
|
||||
let var = split(chunk, '=');
|
||||
if (length(var) != 2)
|
||||
continue;
|
||||
ctx.query_string[var[0]] = var[1];
|
||||
}
|
||||
auth_client(ctx);
|
||||
};
|
||||
|
||||
%}
|
||||
233
feeds/ucentral/uspot/files/usr/share/uspot/handler.uc
Normal file
233
feeds/ucentral/uspot/files/usr/share/uspot/handler.uc
Normal file
@@ -0,0 +1,233 @@
|
||||
{%
|
||||
|
||||
'use strict';
|
||||
|
||||
let fs = require('fs');
|
||||
let rtnl = require('rtnl');
|
||||
let uam = require('uam');
|
||||
|
||||
let file = fs.open('/usr/share/uspot/header', 'r');
|
||||
let header = file.read('all');
|
||||
file.close();
|
||||
|
||||
file = fs.open('/usr/share/uspot/footer', 'r');
|
||||
let footer = file.read('all');
|
||||
file.close();
|
||||
|
||||
let uci = require('uci').cursor();
|
||||
let config = uci.get_all('uspot');
|
||||
|
||||
// fs.open wrapper
|
||||
function fs_open(cmd) {
|
||||
let stdout = fs.popen(cmd);
|
||||
if (!stdout)
|
||||
return null;
|
||||
|
||||
let reply = null;
|
||||
try {
|
||||
reply = json(stdout.read('all'));
|
||||
} catch(e) {
|
||||
|
||||
}
|
||||
stdout.close();
|
||||
return reply;
|
||||
}
|
||||
|
||||
// give a client access to the internet
|
||||
function allow_client(ctx) {
|
||||
system('ubus call spotfilter client_set \'{ "interface": "hotspot", "address": "' + replace(ctx.mac, '-', ':') + '", "state": 1, "dns_state": 1}\'');
|
||||
include('allow.uc', ctx);
|
||||
}
|
||||
|
||||
// delegate an initial connection to the correct handler
|
||||
function request_start(ctx) {
|
||||
switch (config?.config?.auth_mode) {
|
||||
case 'click-to-continue':
|
||||
include('click.uc', ctx);
|
||||
return;
|
||||
case 'credentials':
|
||||
include('credentials.uc', ctx);
|
||||
return;
|
||||
case 'radius':
|
||||
include('radius.uc', ctx);
|
||||
return;
|
||||
case 'uam':
|
||||
ctx.uam_location = config.uam.uam_server +
|
||||
'?res=notyet' +
|
||||
'&uamip=' + ctx.env.SERVER_ADDR +
|
||||
'&uamport=' + config.uam.uam_port +
|
||||
'&challenge=' + uam.md5(config.uam.challenge, ctx.mac) +
|
||||
'&mac=' + replace(ctx.mac, ':', '-') +
|
||||
'&ip=' + ctx.env.REMOTE_ADDR +
|
||||
'&called=' + config.uam.nasmac +
|
||||
'&nasid=' + config.uam.nasid +
|
||||
'&userurl=www.google.com';
|
||||
ctx.uam_location += '&md=' + uam.md5(ctx.uam_location, config.uam.uam_secret);
|
||||
include('uam.uc', ctx);
|
||||
return;
|
||||
default:
|
||||
include('error.uc', ctx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// delegate a local click-to-continue authentication
|
||||
function request_click(ctx) {
|
||||
// make sure this is the right auth_mode
|
||||
if (config?.config?.auth_mode != 'click-to-continue') {
|
||||
include('error.uc', ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if a username and password was provided
|
||||
if (ctx.form_data.accept_terms != 'clicked') {
|
||||
request_start({ ...ctx, error: 1 });
|
||||
return;
|
||||
}
|
||||
allow_client(ctx);
|
||||
}
|
||||
|
||||
// delegate a local username/password authentication
|
||||
function request_credentials(ctx) {
|
||||
// make sure this is the right auth_mode
|
||||
if (config?.config?.auth_mode != 'credentials') {
|
||||
include('error.uc', ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if a username and password was provided
|
||||
if (!ctx.form_data.username || !ctx.form_data.password) {
|
||||
request_start({ ...ctx, error: 1 });
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the credentials are valid
|
||||
for (let k in config) {
|
||||
let cred = config[k];
|
||||
|
||||
if (cred['.type'] != 'credentials')
|
||||
continue;
|
||||
if (ctx.form_data.username != cred.username ||
|
||||
ctx.form_data.password != cred.password)
|
||||
continue;
|
||||
|
||||
allow_client(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// auth failed
|
||||
request_start({ ...ctx, error: 1 });
|
||||
}
|
||||
|
||||
// delegate a radius username/password authentication
|
||||
function request_radius(ctx) {
|
||||
// make sure this is the right auth_mode
|
||||
if (config?.config?.auth_mode != 'radius') {
|
||||
include('error.uc', ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if a username and password was provided
|
||||
if (!ctx.form_data.username || !ctx.form_data.password) {
|
||||
request_start({ ...ctx, error: 1 });
|
||||
return;
|
||||
}
|
||||
|
||||
let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w');
|
||||
cfg.write({
|
||||
type: 'auth',
|
||||
server: sprintf('%s:%s:%s',config.radius.auth_server, config.radius.auth_port, config.radius.auth_secret),
|
||||
username: ctx.form_data.username,
|
||||
password: ctx.form_data.password,
|
||||
acct_session: "0123456789",
|
||||
client_ip: ctx.env.REMOTE_ADDR,
|
||||
called_station: ctx.mac,
|
||||
nas_ip: ctx.env.SERVER_ADDR,
|
||||
});
|
||||
cfg.close();
|
||||
|
||||
let stdout = fs.popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json');
|
||||
let reply;
|
||||
if (!stdout) {
|
||||
request_start({ ...ctx, error: 1 });
|
||||
return;
|
||||
}
|
||||
reply = json(stdout.read('all'));
|
||||
stdout.close();
|
||||
if (reply['access-accept']) {
|
||||
allow_client(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// auth failed
|
||||
request_start({ ...ctx, error: 1 });
|
||||
}
|
||||
|
||||
function PO(id, english) {
|
||||
return english;
|
||||
}
|
||||
|
||||
global.handle_request = function(env) {
|
||||
let mac;
|
||||
let form_data = {};
|
||||
let query_string = {};
|
||||
let post_data = '';
|
||||
let ctx = { env, header, footer, mac, form_data, post_data, query_string, config, PO };
|
||||
|
||||
// lookup the peers MAC
|
||||
let macs = rtnl.request(rtnl.const.RTM_GETNEIGH, rtnl.const.NLM_F_DUMP, { });
|
||||
for (let m in macs)
|
||||
if (m.dst == env.REMOTE_HOST)
|
||||
ctx.mac = replace(m.lladdr, ':', '-');
|
||||
|
||||
// if the MAC lookup failed, go to the error page
|
||||
if (!ctx.mac)
|
||||
include('error.uc', ctx);
|
||||
|
||||
// check if a client is already connected
|
||||
let connected = fs_open('ubus call spotfilter client_get \'{"interface": "hotspot", "address": "' + ctx.mac + '"}\'');
|
||||
if (connected?.state) {
|
||||
include('connected.uc', ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// split QUERY_STRING
|
||||
if (env.QUERY_STRING)
|
||||
for (let chunk in split(env.QUERY_STRING, '&')) {
|
||||
let var = split(chunk, '=');
|
||||
if (length(var) != 2)
|
||||
continue;
|
||||
ctx.query_string[var[0]] = var[1];
|
||||
}
|
||||
|
||||
// recv POST data
|
||||
if (env.CONTENT_LENGTH > 0)
|
||||
for (let chunk = uhttpd.recv(64); chunk != null; chunk = uhttpd.recv(64))
|
||||
post_data += replace(chunk, /[^[:graph:]]/g, '.');
|
||||
|
||||
// split POST data into an array
|
||||
if (post_data)
|
||||
for (let chunk in split(post_data, '&')) {
|
||||
let var = split(chunk, '=');
|
||||
if (length(var) != 2)
|
||||
continue;
|
||||
ctx.form_data[var[0]] = var[1];
|
||||
}
|
||||
|
||||
switch (ctx.form_data.action) {
|
||||
case 'credentials':
|
||||
request_credentials(ctx);
|
||||
return;
|
||||
case 'radius':
|
||||
request_radius(ctx);
|
||||
return;
|
||||
case 'click':
|
||||
request_click(ctx);
|
||||
return;
|
||||
default:
|
||||
request_start(ctx);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
%}
|
||||
25
feeds/ucentral/uspot/files/usr/share/uspot/header
Normal file
25
feeds/ucentral/uspot/files/usr/share/uspot/header
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/images/splash.jpg" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/captive-portal.css">
|
||||
<title>uCentral - Captive Portal</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root">
|
||||
<div class="portal flex-column align-items-center">
|
||||
<div class="container">
|
||||
<div class="justify-content-center row">
|
||||
<div class="col-md-8">
|
||||
<img class="c-sidebar-brand-full" src="/images/OpenWiFi_LogoLockup_DarkGreyColour.svg" alt="OpenWifi" style="padding-left: 17%; width: 85%;">
|
||||
<div class="card">
|
||||
<div class="card-header">uCentral - Captive Portal</div>
|
||||
<div class="card-body">
|
||||
18
feeds/ucentral/uspot/files/usr/share/uspot/radius.uc
Normal file
18
feeds/ucentral/uspot/files/usr/share/uspot/radius.uc
Normal file
@@ -0,0 +1,18 @@
|
||||
Status: 200 OK
|
||||
Content-Type: text/html
|
||||
|
||||
{{ header }}
|
||||
{% if (error): %}
|
||||
<h1> Invalid credentials </h1>
|
||||
{% endif %}
|
||||
|
||||
<form action="/hotspot" method="POST">
|
||||
<label for="fname">Username:</label>
|
||||
<input type="text" name="username"><br>
|
||||
<label for="fname">Password:</label>
|
||||
<input type="password" name="password">
|
||||
<input type="hidden" name="action" value="radius">
|
||||
<input type="submit" value="Login" class="btn btn-primary btn-block">
|
||||
</form>
|
||||
|
||||
{{ footer }}
|
||||
5
feeds/ucentral/uspot/files/usr/share/uspot/uam.uc
Normal file
5
feeds/ucentral/uspot/files/usr/share/uspot/uam.uc
Normal file
@@ -0,0 +1,5 @@
|
||||
Status: 302 Found
|
||||
Location: {{ uam_location }}
|
||||
Content-Type: text/html
|
||||
|
||||
|
||||
11
feeds/ucentral/uspot/files/www-uspot/cpd.html
Normal file
11
feeds/ucentral/uspot/files/www-uspot/cpd.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="refresh" content="0; URL=http://192.168.178.22/hotspot" />
|
||||
</head>
|
||||
<body style="background-color: white">
|
||||
<a style="color: black; font-family: arial, helvetica, sans-serif;" href="http://192.168.178.22/hotspot">HotSpot Login</a>
|
||||
</body>
|
||||
</html>
|
||||
42
feeds/ucentral/uspot/files/www-uspot/cpd.uc
Normal file
42
feeds/ucentral/uspot/files/www-uspot/cpd.uc
Normal file
@@ -0,0 +1,42 @@
|
||||
let uci = require('uci').cursor();
|
||||
let config = uci.get_all('uspot');
|
||||
let fs = require('fs');
|
||||
|
||||
let stdout = fs.popen('env');
|
||||
let raw = stdout.read('all');
|
||||
let lines = split(raw, '\n');
|
||||
let env = {};
|
||||
for (let line in lines) {
|
||||
let e = split(line, '=');
|
||||
if (length(e) == 2)
|
||||
env[e[0]] = e[1];
|
||||
}
|
||||
|
||||
let location;
|
||||
|
||||
switch(config.config.auth_mode) {
|
||||
case 'uam':
|
||||
location = config.uam.server +
|
||||
'?res=notyet' +
|
||||
'&uamip=' + env.SERVER_ADDR +
|
||||
'&uamport=' + config.uam.port +
|
||||
//'&challenge=' +
|
||||
//'&mac=' +
|
||||
'&called=' + config.uam.nasmac +
|
||||
'&nasid=' + config.uam.nasid +
|
||||
// '&sessionid=' + +
|
||||
// userurl
|
||||
// md=
|
||||
"";
|
||||
break;
|
||||
default:
|
||||
location = 'http://' + env.SERVER_ADDR + '/hotspot';
|
||||
}
|
||||
|
||||
system('logger "' + location + '"');
|
||||
|
||||
printf('Status: 302 Found
|
||||
Location: %s
|
||||
Content-Type: text/html
|
||||
|
||||
', location);
|
||||
7
feeds/ucentral/uspot/files/www-uspot/css/bootstrap.min.css
vendored
Normal file
7
feeds/ucentral/uspot/files/www-uspot/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
18
feeds/ucentral/uspot/files/www-uspot/css/captive-portal.css
Normal file
18
feeds/ucentral/uspot/files/www-uspot/css/captive-portal.css
Normal file
@@ -0,0 +1,18 @@
|
||||
.portal {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-height: 100vh;
|
||||
background-color: #ebedef;
|
||||
}
|
||||
|
||||
.align-items-center {
|
||||
align-items: center!important;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
flex-direction: row!important;
|
||||
}
|
||||
|
||||
.justify-content-center {
|
||||
justify-content: center!important;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 141.5 185.6" style="enable-background:new 0 0 141.5 185.6;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#414141;}
|
||||
.st2{fill:#FED206;}
|
||||
.st3{fill:#EB6F53;}
|
||||
.st4{fill:#3BA9B6;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M120.7,183.9H21.5c-10.8,0-19.5-8.7-19.5-19.5V20.5c0-10.8,8.7-19.5,19.5-19.5h99.2
|
||||
c10.8,0,19.5,8.7,19.5,19.5v143.9C140.2,175.2,131.5,183.9,120.7,183.9z"/>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M46.3,166.2v-3.4h-1.2v-0.6h3.1v0.6H47v3.4H46.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M49,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H49z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M52.6,166.2v-4h0.7v3.4h1.8v0.6H52.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M55.7,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H55.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M59.1,164.2c0-1.2,0.9-2.1,2.1-2.1c0.8,0,1.3,0.4,1.6,0.9l-0.6,0.3c-0.2-0.3-0.6-0.6-1-0.6
|
||||
c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.4,0,0.8-0.3,1-0.6l0.6,0.3c-0.3,0.5-0.8,0.9-1.6,0.9
|
||||
C60,166.3,59.1,165.5,59.1,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M63.2,164.2c0-1.2,0.8-2.1,2-2.1c1.2,0,2,0.9,2,2.1c0,1.2-0.8,2.1-2,2.1C64,166.3,63.2,165.4,63.2,164.2z
|
||||
M66.5,164.2c0-0.8-0.5-1.4-1.3-1.4c-0.8,0-1.3,0.6-1.3,1.4c0,0.8,0.5,1.4,1.3,1.4C66,165.7,66.5,165,66.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M71.3,166.2v-3.1l-1.2,3.1h-0.3l-1.2-3.1v3.1h-0.7v-4h1l1.1,2.7l1.1-2.7h1v4H71.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M75.7,166.2v-4h0.7v4H75.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M80.4,166.2l-2.1-2.8v2.8h-0.7v-4h0.7l2,2.8v-2.8h0.7v4H80.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M82.3,166.2v-4H85v0.6h-2v1h2v0.6h-2v1.7H82.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M87.9,166.2l-0.9-1.5h-0.7v1.5h-0.7v-4h1.7c0.8,0,1.3,0.5,1.3,1.2c0,0.7-0.5,1.1-0.9,1.2l1,1.6H87.9z
|
||||
M88,163.5c0-0.4-0.3-0.6-0.7-0.6h-1v1.3h1C87.7,164.1,88,163.9,88,163.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M92.4,166.2l-0.3-0.8h-1.8l-0.3,0.8h-0.8l1.6-4h0.9l1.6,4H92.4z M91.2,162.9l-0.7,1.9h1.4L91.2,162.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M95.8,166.2v-4h1.5c0.8,0,1.2,0.5,1.2,1.2c0,0.6-0.4,1.2-1.2,1.2h-1.2v1.7H95.8z M98.2,163.4
|
||||
c0-0.5-0.3-0.9-0.9-0.9h-1.1v1.7h1.1C97.8,164.3,98.2,163.9,98.2,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M101.5,166.2l-1.1-1.6h-0.9v1.6h-0.3v-4h1.5c0.7,0,1.2,0.4,1.2,1.2c0,0.7-0.5,1.1-1.1,1.1l1.2,1.7H101.5z
|
||||
M101.6,163.4c0-0.5-0.4-0.9-0.9-0.9h-1.1v1.7h1.1C101.2,164.3,101.6,163.9,101.6,163.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M102.8,164.2c0-1.2,0.8-2.1,1.9-2.1c1.2,0,1.9,0.9,1.9,2.1c0,1.2-0.8,2.1-1.9,2.1
|
||||
C103.6,166.3,102.8,165.4,102.8,164.2z M106.3,164.2c0-1-0.6-1.7-1.6-1.7c-1,0-1.6,0.7-1.6,1.7c0,1,0.6,1.7,1.6,1.7
|
||||
C105.7,166,106.3,165.2,106.3,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M106.9,165.8l0.2-0.3c0.2,0.2,0.4,0.4,0.8,0.4c0.5,0,0.9-0.4,0.9-0.9v-2.8h0.3v2.8c0,0.8-0.5,1.2-1.2,1.2
|
||||
C107.5,166.3,107.2,166.1,106.9,165.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M110.4,166.2v-4h2.5v0.3h-2.2v1.5h2.1v0.3h-2.1v1.6h2.2v0.3H110.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M113.5,164.2c0-1.2,0.9-2.1,2-2.1c0.6,0,1.1,0.3,1.5,0.7l-0.3,0.2c-0.3-0.3-0.7-0.6-1.2-0.6
|
||||
c-0.9,0-1.7,0.7-1.7,1.7c0,1,0.7,1.7,1.7,1.7c0.5,0,0.9-0.2,1.2-0.6l0.3,0.2c-0.4,0.4-0.8,0.7-1.5,0.7
|
||||
C114.4,166.3,113.5,165.5,113.5,164.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M118.7,166.2v-3.7h-1.3v-0.3h2.9v0.3H119v3.7H118.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1" points="26.3,163.8 31.6,158.5 36.9,163.8 37.7,163.8 31.6,157.6 25.5,163.8 "/>
|
||||
<polygon class="st1" points="36.9,164.7 31.6,170 26.3,164.7 25.5,164.7 31.6,170.8 37.7,164.7 "/>
|
||||
<polygon class="st1" points="31,163.8 36.3,158.5 41.6,163.8 42.5,163.8 36.3,157.6 30.2,163.8 "/>
|
||||
<polygon class="st1" points="41.6,164.7 36.3,170 31,164.7 30.2,164.7 36.3,170.8 42.5,164.7 "/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M33.2,100.7c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3S37.8,100.7,33.2,100.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M33.2,35.2c40.7,0,73.8,33.1,73.8,73.8c0,0.7,0,1.4,0,2.1c0,1.7,0.6,3.3,1.7,4.6c1.2,1.2,2.8,1.9,4.5,2
|
||||
l0.2,0c3.5,0,6.3-2.7,6.4-6.2c0-0.8,0-1.7,0-2.5c0-47.7-38.8-86.6-86.6-86.6c-0.8,0-1.7,0-2.5,0c-1.7,0-3.3,0.8-4.5,2
|
||||
c-1.2,1.2-1.8,2.9-1.7,4.6c0.1,3.5,3,6.3,6.6,6.2C31.8,35.2,32.5,35.2,33.2,35.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M33.2,60.5c26.7,0,48.5,21.7,48.5,48.5c0,0.6,0,1.3,0,2c-0.1,1.7,0.5,3.3,1.7,4.6c1.2,1.3,2.7,2,4.4,2.1
|
||||
c1.7,0.1,3.3-0.5,4.6-1.7c1.2-1.2,2-2.7,2-4.4c0-0.9,0.1-1.8,0.1-2.6c0-33.8-27.5-61.2-61.2-61.2c-0.8,0-1.6,0-2.6,0.1
|
||||
c-1.7,0.1-3.3,0.8-4.4,2.1c-1.2,1.3-1.8,2.9-1.7,4.6s0.8,3.3,2.1,4.4c1.3,1.2,2.9,1.8,4.6,1.7C31.9,60.5,32.6,60.5,33.2,60.5z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st4" d="M33.2,86.7c12.3,0,22.3,10,22.3,22.3c0,0.5,0,1.1-0.1,1.8c-0.3,3.5,2.3,6.6,5.8,6.9
|
||||
c3.5,0.3,6.6-2.3,6.9-5.8c0.1-1,0.1-1.9,0.1-2.8c0-19.3-15.7-35.1-35.1-35.1c-0.9,0-1.8,0-2.8,0.1c-1.7,0.1-3.2,0.9-4.3,2.2
|
||||
c-1.1,1.3-1.6,2.9-1.5,4.6c0.1,1.7,0.9,3.2,2.2,4.3c1.3,1.1,2.9,1.6,4.6,1.5C32.1,86.7,32.7,86.7,33.2,86.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M35.8,130.4c1.1,0.6,2.1,1.5,2.7,2.6c0.7,1.1,1,2.3,1,3.7s-0.3,2.6-1,3.7c-0.7,1.1-1.6,2-2.7,2.6
|
||||
c-1.1,0.6-2.4,1-3.8,1s-2.7-0.3-3.8-1c-1.1-0.6-2.1-1.5-2.7-2.6c-0.7-1.1-1-2.3-1-3.7c0-1.3,0.3-2.6,1-3.7c0.7-1.1,1.6-2,2.7-2.6
|
||||
c1.1-0.6,2.4-0.9,3.8-0.9C33.4,129.5,34.7,129.8,35.8,130.4z M29.9,132.9c-0.7,0.4-1.2,0.9-1.6,1.6s-0.6,1.4-0.6,2.2
|
||||
c0,0.8,0.2,1.6,0.6,2.3c0.4,0.7,0.9,1.2,1.6,1.6c0.7,0.4,1.4,0.6,2.1,0.6c0.8,0,1.5-0.2,2.1-0.6c0.6-0.4,1.2-0.9,1.5-1.6
|
||||
c0.4-0.7,0.6-1.4,0.6-2.3c0-0.8-0.2-1.6-0.6-2.2s-0.9-1.2-1.5-1.6c-0.6-0.4-1.4-0.6-2.1-0.6C31.3,132.3,30.6,132.5,29.9,132.9z"/>
|
||||
<path class="st1" d="M50.6,133.6c0.8,0.5,1.4,1.1,1.8,2c0.4,0.8,0.6,1.8,0.6,2.9c0,1.1-0.2,2-0.6,2.8c-0.4,0.8-1,1.5-1.8,1.9
|
||||
c-0.8,0.5-1.6,0.7-2.6,0.7c-0.7,0-1.4-0.1-2-0.4s-1.1-0.7-1.5-1.2v5.4h-3.1V133h3.1v1.6c0.4-0.5,0.9-1,1.4-1.2s1.2-0.4,2-0.4
|
||||
C48.9,132.9,49.8,133.1,50.6,133.6z M49.1,140.5c0.5-0.6,0.7-1.3,0.7-2.2c0-0.9-0.2-1.6-0.7-2.1c-0.5-0.6-1.1-0.8-1.9-0.8
|
||||
s-1.4,0.3-1.9,0.8c-0.5,0.6-0.8,1.3-0.8,2.1c0,0.9,0.2,1.6,0.8,2.2s1.1,0.8,1.9,0.8S48.6,141,49.1,140.5z"/>
|
||||
<path class="st1" d="M63.4,134.4c0.9,1,1.4,2.4,1.4,4.2c0,0.3,0,0.6,0,0.7H57c0.2,0.7,0.5,1.2,1,1.6c0.5,0.4,1.1,0.6,1.8,0.6
|
||||
c0.5,0,1-0.1,1.5-0.3s0.9-0.5,1.3-0.9l1.6,1.6c-0.5,0.6-1.2,1.1-2,1.4c-0.8,0.3-1.6,0.5-2.6,0.5c-1.1,0-2.1-0.2-3-0.7
|
||||
s-1.5-1.1-2-1.9c-0.5-0.8-0.7-1.8-0.7-2.9c0-1.1,0.2-2.1,0.7-2.9s1.1-1.5,2-1.9c0.8-0.5,1.8-0.7,2.9-0.7
|
||||
C61.2,132.9,62.5,133.4,63.4,134.4z M61.8,137.5c0-0.7-0.3-1.3-0.7-1.7s-1-0.6-1.7-0.6c-0.7,0-1.2,0.2-1.7,0.6
|
||||
c-0.4,0.4-0.7,1-0.9,1.7H61.8z"/>
|
||||
<path class="st1" d="M76.2,134c0.7,0.7,1.1,1.7,1.1,3v6.8h-3.1v-5.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.5-0.6
|
||||
c-0.8,0-1.4,0.3-1.8,0.8c-0.4,0.5-0.7,1.2-0.7,2v5.3h-3.1V133h3.1v1.9c0.7-1.3,2-2,3.7-2C74.6,132.8,75.5,133.2,76.2,134z"/>
|
||||
<path class="st1" d="M96,129.7h3.3l-4.7,14h-3.3l-2.9-10.1l-3,10.1h-3.2l-4.7-14h3.4l3,10.7l3-10.7H90l3.1,10.7L96,129.7z"/>
|
||||
<path class="st1" d="M103.3,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C102.6,128.2,103,128.3,103.3,128.7z M100.6,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
<path class="st1" d="M106.5,129.7h10.1l0,2.6h-6.9v3.4h6.3v2.6h-6.3v5.3h-3.2V129.7z"/>
|
||||
<path class="st1" d="M120.9,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5
|
||||
c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C120.1,128.2,120.5,128.3,120.9,128.7z M118.1,133h3.1
|
||||
v10.8h-3.1V133z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 251.2 114.2" style="enable-background:new 0 0 251.2 114.2;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FED206;}
|
||||
.st1{fill:#EB6F53;}
|
||||
.st2{fill:#3BA9B6;}
|
||||
.st3{fill:#414141;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M219.6,43.3C219.5,43.3,219.5,43.3,219.6,43.3c-1.3,0-2.2-1-2.2-2.2c0-0.2,0-0.4,0-0.6
|
||||
c0-11.9-9.7-21.6-21.6-21.6c-0.2,0-0.4,0-0.6,0c-1.2,0-2.2-0.9-2.2-2.1c0-1.2,0.9-2.2,2.1-2.2c0.2,0,0.5,0,0.7,0
|
||||
c14.3,0,25.9,11.6,25.9,25.9c0,0.2,0,0.5,0,0.7C221.7,42.4,220.7,43.3,219.6,43.3z"/>
|
||||
<path class="st1" d="M212.1,43.3C212,43.3,212,43.3,212.1,43.3c-1.3-0.1-2.2-1.1-2.2-2.3c0-0.2,0-0.4,0-0.6
|
||||
c0-7.7-6.3-14.1-14.1-14.1c-0.2,0-0.4,0-0.6,0c-1.2,0.1-2.2-0.9-2.3-2.1c0-1.2,0.9-2.2,2.1-2.3c0.3,0,0.5,0,0.8,0
|
||||
c10.2,0,18.4,8.3,18.4,18.4c0,0.2,0,0.5,0,0.8C214.2,42.4,213.2,43.3,212.1,43.3z"/>
|
||||
<path class="st2" d="M204.3,43.3c-0.1,0-0.1,0-0.2,0c-1.2-0.1-2.1-1.1-2-2.3c0-0.2,0-0.4,0-0.5c0-3.5-2.8-6.3-6.3-6.3
|
||||
c-0.1,0-0.3,0-0.5,0c-1.2,0.1-2.3-0.8-2.3-2c-0.1-1.2,0.8-2.3,2-2.3c0.3,0,0.6,0,0.9,0c5.9,0,10.7,4.8,10.7,10.7c0,0.3,0,0.5,0,0.9
|
||||
C206.4,42.4,205.4,43.3,204.3,43.3z"/>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M61.9,89.9v-4.7h-1.7v-0.9h4.4v0.9h-1.7v4.7H61.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M65.6,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8V89h2.9v0.9H65.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M70.7,89.9v-5.6h1V89h2.5v0.9H70.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M74.9,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8V89h2.9v0.9H74.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M79.8,87.1c0-1.7,1.3-2.9,2.9-2.9c1.1,0,1.8,0.6,2.2,1.3l-0.8,0.4c-0.3-0.5-0.8-0.8-1.4-0.8
|
||||
c-1.1,0-1.9,0.8-1.9,2c0,1.2,0.8,2,1.9,2c0.6,0,1.1-0.4,1.4-0.8l0.8,0.4c-0.4,0.7-1.1,1.3-2.2,1.3C81.1,90,79.8,88.8,79.8,87.1z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M85.5,87.1c0-1.7,1.2-2.9,2.9-2.9c1.7,0,2.9,1.2,2.9,2.9S90,90,88.3,90C86.7,90,85.5,88.8,85.5,87.1z
|
||||
M90.2,87.1c0-1.2-0.7-2-1.9-2c-1.1,0-1.9,0.9-1.9,2c0,1.1,0.7,2,1.9,2C89.5,89.1,90.2,88.3,90.2,87.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M96.9,89.9v-4.3l-1.7,4.3h-0.4l-1.7-4.3v4.3h-1v-5.6h1.4l1.5,3.8l1.5-3.8h1.4v5.6H96.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M103,89.9v-5.6h1v5.6H103z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M109.7,89.9l-2.9-4v4h-1v-5.6h1l2.9,3.9v-3.9h1v5.6H109.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M112.4,89.9v-5.6h3.8v0.9h-2.9v1.4h2.8v0.9h-2.8v2.4H112.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M120.3,89.9l-1.2-2.1h-1v2.1h-1v-5.6h2.5c1.1,0,1.8,0.7,1.8,1.8c0,1-0.7,1.5-1.3,1.6l1.4,2.2H120.3z
|
||||
M120.4,86.1c0-0.5-0.4-0.9-1-0.9h-1.4V87h1.4C120,87,120.4,86.6,120.4,86.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M126.6,89.9l-0.4-1.1h-2.6l-0.4,1.1h-1.1l2.2-5.6h1.2l2.2,5.6H126.6z M124.9,85.3l-1,2.7h2L124.9,85.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M131.4,89.9v-5.6h2.1c1.1,0,1.7,0.8,1.7,1.6c0,0.9-0.6,1.6-1.7,1.6h-1.6v2.3H131.4z M134.7,86
|
||||
c0-0.7-0.5-1.2-1.2-1.2h-1.6v2.4h1.6C134.2,87.2,134.7,86.6,134.7,86z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M139.4,89.9l-1.6-2.3h-1.2v2.3h-0.5v-5.6h2.1c1,0,1.7,0.6,1.7,1.6c0,1-0.7,1.6-1.6,1.6l1.6,2.3H139.4z
|
||||
M139.4,86c0-0.7-0.5-1.2-1.2-1.2h-1.6v2.4h1.6C138.9,87.2,139.4,86.7,139.4,86z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M141.2,87.1c0-1.6,1.1-2.9,2.7-2.9c1.6,0,2.7,1.3,2.7,2.9c0,1.6-1.1,2.9-2.7,2.9
|
||||
C142.3,90,141.2,88.8,141.2,87.1z M146.1,87.1c0-1.4-0.9-2.5-2.2-2.5c-1.4,0-2.2,1-2.2,2.5c0,1.4,0.9,2.5,2.2,2.5
|
||||
C145.2,89.6,146.1,88.5,146.1,87.1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M147,89.3l0.3-0.4c0.3,0.3,0.6,0.6,1.1,0.6c0.8,0,1.2-0.5,1.2-1.3v-4h0.5v4c0,1.2-0.8,1.7-1.7,1.7
|
||||
C147.9,90,147.4,89.8,147,89.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M151.8,89.9v-5.6h3.5v0.4h-3.1v2.1h3v0.4h-3v2.2h3.1v0.4H151.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M156.3,87.1c0-1.7,1.3-2.9,2.8-2.9c0.9,0,1.6,0.4,2,1l-0.4,0.3c-0.4-0.5-1-0.8-1.6-0.8
|
||||
c-1.3,0-2.3,1-2.3,2.5c0,1.4,1,2.5,2.3,2.5c0.7,0,1.3-0.3,1.6-0.8l0.4,0.3c-0.5,0.6-1.2,1-2,1C157.5,90,156.3,88.8,156.3,87.1z"
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M163.5,89.9v-5.2h-1.8v-0.4h4.1v0.4H164v5.2H163.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st3" points="33.7,86.5 41.2,79 48.6,86.5 49.8,86.5 41.2,77.9 32.6,86.5 "/>
|
||||
<polygon class="st3" points="48.6,87.8 41.2,95.2 33.7,87.8 32.6,87.8 41.2,96.4 49.8,87.8 "/>
|
||||
<polygon class="st3" points="40.3,86.5 47.8,79 55.3,86.5 56.4,86.5 47.8,77.9 39.2,86.5 "/>
|
||||
<polygon class="st3" points="55.3,87.8 47.8,95.2 40.3,87.8 39.2,87.8 47.8,96.4 56.4,87.8 "/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M51.2,41.3c2,1.1,3.6,2.6,4.7,4.5c1.1,1.9,1.7,4,1.7,6.4c0,2.3-0.6,4.5-1.7,6.4c-1.1,1.9-2.7,3.4-4.7,4.6
|
||||
c-2,1.1-4.2,1.7-6.6,1.7c-2.4,0-4.6-0.6-6.6-1.7c-2-1.1-3.6-2.6-4.7-4.6c-1.1-1.9-1.7-4.1-1.7-6.4c0-2.3,0.6-4.5,1.7-6.4
|
||||
c1.1-1.9,2.7-3.4,4.7-4.5c2-1.1,4.2-1.6,6.6-1.6C47,39.6,49.2,40.2,51.2,41.3z M40.5,44.9c-1.3,0.7-2.3,1.7-3,3
|
||||
c-0.7,1.3-1.1,2.7-1.1,4.2s0.4,3,1.1,4.2c0.8,1.3,1.8,2.3,3,3c1.3,0.7,2.7,1.1,4.1,1.1c1.5,0,2.8-0.4,4.1-1.1c1.3-0.7,2.3-1.8,3-3
|
||||
c0.7-1.3,1.1-2.7,1.1-4.2s-0.4-2.9-1.1-4.2c-0.7-1.3-1.7-2.3-3-3c-1.3-0.7-2.6-1.1-4.1-1.1C43.2,43.8,41.8,44.2,40.5,44.9z"/>
|
||||
<path class="st3" d="M76.9,46.8c1.3,0.8,2.4,1.9,3.1,3.4c0.7,1.4,1.1,3.1,1.1,5c0,1.9-0.4,3.5-1.1,4.9c-0.7,1.4-1.8,2.5-3.1,3.3
|
||||
c-1.3,0.8-2.9,1.2-4.6,1.2c-1.4,0-2.6-0.3-3.7-0.8c-1.1-0.5-2-1.3-2.7-2.4v9.8h-4.6V45.7H66v3.1c0.7-1.1,1.5-1.8,2.6-2.4
|
||||
c1.1-0.5,2.3-0.8,3.7-0.8C74,45.6,75.6,46,76.9,46.8z M75.1,59.1c1-1.1,1.5-2.4,1.5-4.1c0-1.7-0.5-3-1.5-4.1
|
||||
c-1-1.1-2.2-1.6-3.8-1.6c-1.6,0-2.8,0.5-3.8,1.6c-1,1-1.5,2.4-1.5,4.1c0,1.7,0.5,3,1.5,4.1c1,1.1,2.3,1.6,3.8,1.6
|
||||
C72.8,60.7,74.1,60.2,75.1,59.1z"/>
|
||||
<path class="st3" d="M99.3,48.1c1.5,1.7,2.3,4.1,2.3,7.2c0,0.6,0,1.1,0,1.4H87.7c0.3,1.3,0.9,2.4,1.9,3.1c0.9,0.8,2.1,1.1,3.5,1.1
|
||||
c1,0,1.9-0.2,2.7-0.5c0.9-0.4,1.6-0.9,2.3-1.6l2.5,2.6c-0.9,1-2.1,1.8-3.4,2.4c-1.3,0.6-2.8,0.8-4.5,0.8c-1.9,0-3.6-0.4-5.1-1.2
|
||||
c-1.5-0.8-2.6-1.9-3.4-3.3c-0.8-1.4-1.2-3.1-1.2-5c0-1.9,0.4-3.5,1.2-5c0.8-1.4,1.9-2.6,3.4-3.4c1.4-0.8,3.1-1.2,4.9-1.2
|
||||
C95.5,45.6,97.8,46.4,99.3,48.1z M97.4,53.6c0-1.4-0.5-2.5-1.4-3.3c-0.9-0.8-2-1.2-3.4-1.2c-1.3,0-2.4,0.4-3.3,1.2
|
||||
c-0.9,0.8-1.5,1.9-1.7,3.3H97.4z"/>
|
||||
<path class="st3" d="M121.5,47.5c1.2,1.3,1.9,3.1,1.9,5.3v11.7h-4.6V54.1c0-1.3-0.4-2.3-1.1-3.1c-0.7-0.8-1.8-1.1-3-1.1
|
||||
c-1.5,0-2.7,0.5-3.6,1.5s-1.3,2.3-1.3,3.8v9.2h-4.5V45.7h4.5v3.5c1.3-2.4,3.5-3.6,6.7-3.7C118.5,45.5,120.2,46.2,121.5,47.5z"/>
|
||||
<path class="st3" d="M156.5,39.9h4.9l-8.3,24.5h-4.9l-5.6-18.6l-5.7,18.6h-4.8l-8.3-24.5h5l5.8,19.4l5.7-19.4h4.6l5.8,19.5
|
||||
L156.5,39.9z"/>
|
||||
<path class="st3" d="M168,38.4c0.5,0.5,0.7,1.2,0.7,2c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.9,0.8c-0.7,0-1.4-0.3-1.9-0.8
|
||||
c-0.5-0.5-0.7-1.2-0.7-1.9c0-0.8,0.2-1.4,0.7-2c0.5-0.5,1.1-0.8,1.9-0.8C166.9,37.7,167.6,37.9,168,38.4z M164,45.7h4.5v18.7H164
|
||||
V45.7z"/>
|
||||
<path class="st3" d="M174,39.9h16.9l0,4.1h-12.2v6.6h11.1v4.1h-11.1v9.7H174V39.9z"/>
|
||||
<path class="st3" d="M197.9,38.4c0.5,0.5,0.7,1.2,0.7,2c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.9,0.8c-0.7,0-1.4-0.3-1.9-0.8
|
||||
c-0.5-0.5-0.7-1.2-0.7-1.9c0-0.8,0.2-1.4,0.7-2c0.5-0.5,1.1-0.8,1.9-0.8C196.8,37.7,197.4,37.9,197.9,38.4z M193.8,45.7h4.5v18.7
|
||||
h-4.5V45.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
11
feeds/ucentral/uspot/files/www-uspot/index.html
Normal file
11
feeds/ucentral/uspot/files/www-uspot/index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="refresh" content="0; URL=http://192.168.178.22/hotspot" />
|
||||
</head>
|
||||
<body style="background-color: white">
|
||||
<a style="color: black; font-family: arial, helvetica, sans-serif;" href="http://192.168.178.22/hotspot">HotSpot Login</a>
|
||||
</body>
|
||||
</html>
|
||||
17
feeds/ucentral/uspot/src/CMakeLists.txt
Normal file
17
feeds/ucentral/uspot/src/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
PROJECT(radius-client C)
|
||||
INCLUDE(GNUInstallDirs)
|
||||
ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
|
||||
|
||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
|
||||
ADD_EXECUTABLE(radius-client radius.c)
|
||||
TARGET_LINK_LIBRARIES(radius-client radcli ubox blobmsg_json)
|
||||
INSTALL(TARGETS radius-client
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
|
||||
)
|
||||
|
||||
ADD_LIBRARY(uam SHARED uam.c)
|
||||
TARGET_LINK_LIBRARIES(uam ubox)
|
||||
INSTALL(TARGETS uam LIBRARY DESTINATION lib)
|
||||
305
feeds/ucentral/uspot/src/radius.c
Normal file
305
feeds/ucentral/uspot/src/radius.c
Normal file
@@ -0,0 +1,305 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <radcli/radcli.h>
|
||||
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
enum {
|
||||
RADIUS_TYPE,
|
||||
RADIUS_SERVER,
|
||||
RADIUS_USERNAME,
|
||||
RADIUS_PASSWORD,
|
||||
RADIUS_ACCT_SESSION,
|
||||
RADIUS_CLIENT_IP,
|
||||
RADIUS_CALLED_STATION,
|
||||
RADIUS_CALLING_STATION,
|
||||
RADIUS_NAS_IP,
|
||||
RADIUS_NAS_ID,
|
||||
__RADIUS_MAX,
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = {
|
||||
[RADIUS_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_SERVER] = { .name = "server", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_ACCT_SESSION] = { .name = "acct_session", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_CLIENT_IP] = { .name = "client_ip", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_CALLED_STATION] = { .name = "called_station", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_CALLING_STATION] = { .name = "calling_station", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_NAS_IP] = { .name = "nas_ip", .type = BLOBMSG_TYPE_STRING },
|
||||
[RADIUS_NAS_ID] = { .name = "nas_id", .type = BLOBMSG_TYPE_STRING },
|
||||
};
|
||||
|
||||
static struct config {
|
||||
char *type;
|
||||
char *server;
|
||||
char *username;
|
||||
char *password;
|
||||
char *acct_session;
|
||||
struct sockaddr_in client_ip;
|
||||
char *called_station;
|
||||
char *calling_station;
|
||||
struct sockaddr_in nas_ip;
|
||||
char *nas_id;
|
||||
} config;
|
||||
|
||||
static struct blob_buf b = {};
|
||||
static struct blob_attr *tb[__RADIUS_MAX] = {};
|
||||
|
||||
static int
|
||||
result(rc_handle const *rh, int accept, VALUE_PAIR *pair)
|
||||
{
|
||||
struct blob_buf b = {};
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
blobmsg_add_u32(&b, "access-accept", accept);
|
||||
|
||||
if (pair) {
|
||||
void *c = blobmsg_open_table(&b, "reply");
|
||||
char name[33], value[256];
|
||||
VALUE_PAIR *vp;
|
||||
|
||||
for (vp = pair; vp != NULL; vp = vp->next) {
|
||||
if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
|
||||
sizeof(value)) == -1)
|
||||
break;
|
||||
blobmsg_add_string(&b, name, value);
|
||||
}
|
||||
blobmsg_close_table(&b, c);
|
||||
}
|
||||
printf("%s", blobmsg_format_json(b.head, true));
|
||||
|
||||
return accept;
|
||||
}
|
||||
|
||||
static void
|
||||
config_load(void)
|
||||
{
|
||||
if (tb[RADIUS_TYPE])
|
||||
config.type = blobmsg_get_string(tb[RADIUS_TYPE]);
|
||||
|
||||
if (tb[RADIUS_SERVER])
|
||||
config.server = blobmsg_get_string(tb[RADIUS_SERVER]);
|
||||
|
||||
if (tb[RADIUS_USERNAME])
|
||||
config.username = blobmsg_get_string(tb[RADIUS_USERNAME]);
|
||||
|
||||
if (tb[RADIUS_PASSWORD])
|
||||
config.password = blobmsg_get_string(tb[RADIUS_PASSWORD]);
|
||||
|
||||
if (tb[RADIUS_ACCT_SESSION])
|
||||
config.acct_session = blobmsg_get_string(tb[RADIUS_ACCT_SESSION]);
|
||||
|
||||
if (tb[RADIUS_CLIENT_IP]) {
|
||||
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_CLIENT_IP]), &(config.client_ip.sin_addr));
|
||||
config.client_ip.sin_addr.s_addr = ntohl(config.client_ip.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
if (tb[RADIUS_CALLED_STATION])
|
||||
config.called_station = blobmsg_get_string(tb[RADIUS_CALLED_STATION]);
|
||||
|
||||
if (tb[RADIUS_CALLING_STATION])
|
||||
config.calling_station = blobmsg_get_string(tb[RADIUS_CALLING_STATION]);
|
||||
|
||||
if (tb[RADIUS_NAS_IP]) {
|
||||
inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_NAS_IP]), &(config.nas_ip.sin_addr));
|
||||
config.nas_ip.sin_addr.s_addr = ntohl(config.nas_ip.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
if (tb[RADIUS_NAS_ID])
|
||||
config.nas_id = blobmsg_get_string(tb[RADIUS_NAS_ID]);
|
||||
}
|
||||
|
||||
static rc_handle *
|
||||
radius_init(void)
|
||||
{
|
||||
rc_handle *rh = rc_new();
|
||||
if (rh == NULL)
|
||||
return NULL;
|
||||
|
||||
rh = rc_config_init(rh);
|
||||
if (rh == NULL)
|
||||
return NULL;
|
||||
|
||||
rc_add_config(rh, "authserver", config.server, "code", __LINE__);
|
||||
rc_add_config(rh, "servers", "/tmp/radius.servers", "code", __LINE__);
|
||||
rc_add_config(rh, "dictionary", "/etc/radcli/dictionary", "code", __LINE__);
|
||||
rc_add_config(rh, "radius_timeout", "5", "code", __LINE__);
|
||||
rc_add_config(rh, "radius_retries", "1", "code", __LINE__);
|
||||
rc_add_config(rh, "bindaddr", "*", "code", __LINE__);
|
||||
|
||||
if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
|
||||
return NULL;
|
||||
|
||||
return rh;
|
||||
}
|
||||
|
||||
static int
|
||||
auth(void)
|
||||
{
|
||||
VALUE_PAIR *send = NULL, *received;
|
||||
rc_handle *rh = NULL;
|
||||
|
||||
if (!config.server || !config.username || !config.password)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
rh = radius_init();
|
||||
if (!rh)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
rc_apply_config(rh);
|
||||
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
|
||||
return result(rh, 1, received);
|
||||
|
||||
return result(rh, 0, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
uam_auth(void)
|
||||
{
|
||||
VALUE_PAIR *send = NULL, *received;
|
||||
rc_handle *rh = NULL;
|
||||
|
||||
if (!config.server || !config.username || !config.password ||
|
||||
!config.acct_session || !config.called_station ||
|
||||
!config.calling_station || !config.nas_id)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
rh = radius_init();
|
||||
if (!rh)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
//if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
//if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
rc_apply_config(rh);
|
||||
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
|
||||
return result(rh, 1, received);
|
||||
|
||||
return result(rh, 0, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
uam_acct(void)
|
||||
{
|
||||
VALUE_PAIR *send = NULL, *received;
|
||||
rc_handle *rh = NULL;
|
||||
|
||||
if (!config.server || !config.username || !config.password ||
|
||||
!config.acct_session || !config.called_station ||
|
||||
!config.calling_station || !config.nas_id)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
rh = radius_init();
|
||||
if (!rh)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
//if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
//if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL)
|
||||
// return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL)
|
||||
return result(rh, 0, NULL);
|
||||
|
||||
rc_apply_config(rh);
|
||||
if (rc_auth(rh, 0, send, &received, NULL) == OK_RC)
|
||||
return result(rh, 1, received);
|
||||
|
||||
return result(rh, 0, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
if (!blobmsg_add_json_from_file(&b, argv[1]))
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
blobmsg_parse(radius_policy, __RADIUS_MAX, tb, blob_data(b.head), blob_len(b.head));
|
||||
|
||||
config_load();
|
||||
if (!config.type)
|
||||
return result(NULL, 0, NULL);
|
||||
|
||||
if (!strcmp(config.type, "auth"))
|
||||
return auth();
|
||||
|
||||
if (!strcmp(config.type, "uam-auth"))
|
||||
return uam_auth();
|
||||
|
||||
if (!strcmp(config.type, "uam-acct"))
|
||||
return uam_acct();
|
||||
|
||||
return result(NULL, 0, NULL);
|
||||
}
|
||||
107
feeds/ucentral/uspot/src/uam.c
Normal file
107
feeds/ucentral/uspot/src/uam.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* SPDX-License-Identifier: ISC */
|
||||
|
||||
/* Copyright (C) 2022 John Crispin <john@phrozen.org> */
|
||||
|
||||
#include <ucode/module.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libubox/md5.h>
|
||||
|
||||
#define MIN(a, b) ((a > b) ? b : a)
|
||||
|
||||
static int
|
||||
hex_to_str(char *in, char *out, int olen)
|
||||
{
|
||||
int ilen = strlen(in);
|
||||
int len = 0;
|
||||
|
||||
while (ilen >= 2 && olen > 1) {
|
||||
int c;
|
||||
sscanf(in, "%2x", &c);
|
||||
*out++ = (char) c;
|
||||
|
||||
in += 2;
|
||||
ilen -= 2;
|
||||
len++;
|
||||
}
|
||||
*out = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_password(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *_chal = uc_fn_arg(0);
|
||||
uc_value_t *_pass = uc_fn_arg(1);
|
||||
uc_value_t *_secret = uc_fn_arg(2);
|
||||
char pass[32];
|
||||
char chal[32];
|
||||
char uamchal[32];
|
||||
char cleartext[32] = {};
|
||||
int plen;
|
||||
int clen;
|
||||
char *secret;
|
||||
int i;
|
||||
md5_ctx_t md5 = {};
|
||||
|
||||
if (!_chal || !_pass || !_secret)
|
||||
return ucv_boolean_new(false);
|
||||
|
||||
plen = hex_to_str(ucv_to_string(vm, _pass), pass, sizeof(pass));
|
||||
clen = hex_to_str(ucv_to_string(vm, _chal), chal, sizeof(chal));
|
||||
secret = ucv_to_string(vm, _secret);
|
||||
|
||||
md5_begin(&md5);
|
||||
md5_hash(chal, clen, &md5);
|
||||
md5_hash(secret, strlen(secret), &md5);
|
||||
md5_end(uamchal, &md5);
|
||||
|
||||
for (i = 0; i < MIN(plen, 16); i++)
|
||||
cleartext[i] = pass[i] ^ uamchal[i];
|
||||
|
||||
return ucv_string_new(cleartext);
|
||||
|
||||
}
|
||||
|
||||
static uc_value_t *
|
||||
uc_md5(uc_vm_t *vm, size_t nargs)
|
||||
{
|
||||
uc_value_t *_str = uc_fn_arg(0);
|
||||
uc_value_t *_secret = uc_fn_arg(1);
|
||||
char _md[32] = {};
|
||||
char md[33] = {};
|
||||
char *secret;
|
||||
char *str;
|
||||
md5_ctx_t md5 = {};
|
||||
int i = 0;
|
||||
|
||||
if (!_str || !_secret)
|
||||
return ucv_boolean_new(false);
|
||||
|
||||
str = ucv_to_string(vm, _str);
|
||||
secret = ucv_to_string(vm, _secret);
|
||||
|
||||
md5_begin(&md5);
|
||||
md5_hash(str, strlen(str), &md5);
|
||||
md5_hash(secret, strlen(secret), &md5);
|
||||
md5_end(_md, &md5);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
sprintf(&md[2 * i], "%02X", _md[i]);
|
||||
|
||||
return ucv_string_new(md);
|
||||
}
|
||||
|
||||
static const uc_function_list_t global_fns[] = {
|
||||
{ "password", uc_password },
|
||||
{ "md5", uc_md5 },
|
||||
};
|
||||
|
||||
void
|
||||
uc_module_init(uc_vm_t *vm, uc_value_t *scope)
|
||||
{
|
||||
uc_function_list_register(scope, global_fns);
|
||||
}
|
||||
Reference in New Issue
Block a user