Skip to content

Commit 7d80a9b

Browse files
committed
Search for the shared secret of the switch
1 parent f5b5e95 commit 7d80a9b

File tree

4 files changed

+214
-48
lines changed

4 files changed

+214
-48
lines changed

go/chisel/server/server_handler.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ func (s *Server) handleWebsocket(w http.ResponseWriter, req *http.Request) {
178178

179179
localSecret := pfconfigdriver.LocalSecret{}
180180
pfconfigdriver.FetchDecodeSocket(req.Context(), &localSecret)
181+
182+
//
181183
//successfuly validated config!
182184
r.Reply(true, nil)
183185
//tunnel per ssh connection

go/chisel/server/server_listen.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"crypto/x509"
66
"errors"
77
"fmt"
8-
"io/ioutil"
98
"net"
109
"os"
1110
"os/user"
@@ -15,7 +14,7 @@ import (
1514
"golang.org/x/crypto/acme/autocert"
1615
)
1716

18-
//TLSConfig enables configures TLS
17+
// TLSConfig enables configures TLS
1918
type TLSConfig struct {
2019
Key string
2120
Cert string
@@ -44,12 +43,12 @@ func (s *Server) listener(host, port string) (net.Listener, error) {
4443
extra = " (WARNING: LetsEncrypt will attempt to connect to your domain on port 443)"
4544
}
4645
}
47-
//tcp listen
46+
// tcp listen
4847
l, err := net.Listen("tcp", host+":"+port)
4948
if err != nil {
5049
return nil, err
5150
}
52-
//optionally wrap in tls
51+
// optionally wrap in tls
5352
proto := "http"
5453
if tlsConf != nil {
5554
proto += "s"
@@ -64,7 +63,7 @@ func (s *Server) listener(host, port string) (net.Listener, error) {
6463
}
6564

6665
func (s *Server) tlsLetsEncrypt(domains []string) *tls.Config {
67-
//prepare cert manager
66+
// prepare cert manager
6867
m := &autocert.Manager{
6968
Prompt: func(tosURL string) bool {
7069
s.Infof("Accepting LetsEncrypt TOS and fetching certificate...")
@@ -73,7 +72,7 @@ func (s *Server) tlsLetsEncrypt(domains []string) *tls.Config {
7372
Email: settings.Env("LE_EMAIL"),
7473
HostPolicy: autocert.HostWhitelist(domains...),
7574
}
76-
//configure file cache
75+
// configure file cache
7776
c := settings.Env("LE_CACHE")
7877
if c == "" {
7978
h := os.Getenv("HOME")
@@ -88,7 +87,7 @@ func (s *Server) tlsLetsEncrypt(domains []string) *tls.Config {
8887
s.Infof("LetsEncrypt cache directory %s", c)
8988
m.Cache = autocert.DirCache(c)
9089
}
91-
//return lets-encrypt tls config
90+
// return lets-encrypt tls config
9291
return m.TLSConfig()
9392
}
9493

@@ -97,11 +96,11 @@ func (s *Server) tlsKeyCert(key, cert string, ca string) (*tls.Config, error) {
9796
if err != nil {
9897
return nil, err
9998
}
100-
//file based tls config using tls defaults
99+
// file based tls config using tls defaults
101100
c := &tls.Config{
102101
Certificates: []tls.Certificate{keypair},
103102
}
104-
//mTLS requires server's CA
103+
// mTLS requires server's CA
105104
if ca != "" {
106105
if err := addCA(ca, c); err != nil {
107106
return nil, err
@@ -118,37 +117,37 @@ func addCA(ca string, c *tls.Config) error {
118117
}
119118
clientCAPool := x509.NewCertPool()
120119
if fileInfo.IsDir() {
121-
//this is a directory holding CA bundle files
122-
files, err := ioutil.ReadDir(ca)
120+
// this is a directory holding CA bundle files
121+
files, err := os.ReadDir(ca)
123122
if err != nil {
124123
return err
125124
}
126-
//add all cert files from path
125+
// add all cert files from path
127126
for _, file := range files {
128127
f := file.Name()
129128
if err := addPEMFile(filepath.Join(ca, f), clientCAPool); err != nil {
130129
return err
131130
}
132131
}
133132
} else {
134-
//this is a CA bundle file
133+
// this is a CA bundle file
135134
if err := addPEMFile(ca, clientCAPool); err != nil {
136135
return err
137136
}
138137
}
139-
//set client CAs and enable cert verification
138+
// set client CAs and enable cert verification
140139
c.ClientCAs = clientCAPool
141140
c.ClientAuth = tls.RequireAndVerifyClientCert
142141
return nil
143142
}
144143

145144
func addPEMFile(path string, pool *x509.CertPool) error {
146-
content, err := ioutil.ReadFile(path)
145+
content, err := os.ReadFile(path)
147146
if err != nil {
148147
return err
149148
}
150149
if !pool.AppendCertsFromPEM(content) {
151-
return errors.New("Fail to load certificates from : " + path)
150+
return fmt.Errorf("fail to load certificates from : %s", path)
152151
}
153152
return nil
154153
}

go/chisel/share/radius_proxy/proxy.go

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package radius_proxy
22

33
import (
4+
"context"
45
"crypto/hmac"
56
"crypto/md5"
67
"errors"
8+
"net"
9+
"strings"
710
"time"
811

912
"github.com/google/uuid"
1013
"github.com/inverse-inc/packetfence/go/chisel/share/cio"
14+
"github.com/inverse-inc/packetfence/go/pfconfigdriver"
1115
"layeh.com/radius"
1216
"layeh.com/radius/rfc2865"
1317
"layeh.com/radius/rfc2869"
@@ -95,10 +99,17 @@ func (rp *Proxy) ProxyPacket(payload []byte, connectorID string) ([]byte, string
9599
}
96100

97101
packet.Attributes.Add(26, vsa)
98-
// err = addMessageAuthenticator(packet, []byte(rp.secret))
99-
// if err != nil {
100-
// return nil, "", err
101-
// }
102+
103+
secret, err := rp.foundSecret(context.Background(), packet)
104+
105+
if err != nil {
106+
secret = string(rp.secret)
107+
}
108+
109+
err = addMessageAuthenticator(packet, []byte(secret))
110+
if err != nil {
111+
return nil, "", err
112+
}
102113

103114
b2, err := packet.Encode()
104115
if err != nil {
@@ -131,3 +142,62 @@ func addMessageAuthenticator(p *radius.Packet, secret []byte) error {
131142
rfc2869.MessageAuthenticator_Set(p, hash.Sum(nil))
132143
return nil
133144
}
145+
146+
func (rp *Proxy) foundSecret(ctx context.Context, packet *radius.Packet) (string, error) {
147+
148+
var SwitchID []string
149+
SwitchMAC := rfc2865.CallingStationID_GetString(packet)
150+
if SwitchMAC != "" {
151+
MacHW, err := net.ParseMAC(SwitchMAC)
152+
if err == nil {
153+
SwitchMAC = MacHW.String()
154+
SwitchID = append(SwitchID, SwitchMAC)
155+
}
156+
}
157+
158+
SwitchNasIP := rfc2865.NASIPAddress_Get(packet)
159+
if SwitchNasIP != nil {
160+
SwitchID = append(SwitchID, SwitchNasIP.String())
161+
}
162+
163+
switches := pfconfigdriver.PfSwitches{}
164+
pfconfigdriver.FetchDecodeSocket(ctx, &switches)
165+
166+
for _, switchID := range SwitchID {
167+
168+
// Find the switch with the given ID
169+
for _, sw := range switches.PfconfigKeys.Keys {
170+
if sw != switchID {
171+
continue
172+
}
173+
switche := pfconfigdriver.PfConfSwitch{}
174+
switche.PfconfigHashNS = sw
175+
pfconfigdriver.FetchDecodeSocket(ctx, &switche)
176+
if switche.RadiusSecret.String() != "" {
177+
return switche.RadiusSecret.String(), nil
178+
}
179+
}
180+
// Find the switch within the ip ranges
181+
if IsIPv4(net.ParseIP(switchID)) {
182+
for _, sw := range switches.PfconfigKeys.Keys {
183+
_, network, err := net.ParseCIDR(sw)
184+
if err != nil {
185+
continue
186+
}
187+
if network.Contains(net.ParseIP(switchID)) {
188+
switche := pfconfigdriver.PfConfSwitch{}
189+
switche.PfconfigHashNS = sw
190+
pfconfigdriver.FetchDecodeSocket(ctx, &switche)
191+
if switche.RadiusSecret.String() != "" {
192+
return switche.RadiusSecret.String(), nil
193+
}
194+
}
195+
}
196+
}
197+
}
198+
return "", errors.New("No secret found")
199+
}
200+
201+
func IsIPv4(address net.IP) bool {
202+
return strings.Count(address.String(), ":") < 2
203+
}

go/pfconfigdriver/structs.go

Lines changed: 123 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -579,34 +579,34 @@ type ClusterSummary struct {
579579

580580
type PfConfAdvanced struct {
581581
StructConfig
582-
PfconfigMethod string `val:"hash_element"`
583-
PfconfigNS string `val:"config::Pf"`
584-
PfconfigHashNS string `val:"advanced"`
585-
HashingCost string `json:"hashing_cost"`
586-
ScanOnAccounting string `json:"scan_on_accounting"`
587-
PffilterProcesses string `json:"pffilter_processes"`
588-
UpdateIplogWithAccounting string `json:"update_iplog_with_accounting"`
589-
UpdateIplogWithAuthentication string `json:"update_iplog_with_authentication"`
590-
AdminCspSecurityHeaders string `json:"admin_csp_security_headers"`
591-
Multihost string `json:"multihost"`
592-
SsoOnAccessReevaluation string `json:"sso_on_access_reevaluation"`
593-
DisablePfDomainAuth string `json:"disable_pf_domain_auth"`
594-
TimingStatsLevel string `json:"timing_stats_level"`
595-
SsoOnDhcp string `json:"sso_on_dhcp"`
596-
Language string `json:"language"`
597-
StatsdListenPort string `json:"statsd_listen_port"`
598-
SsoOnAccounting string `json:"sso_on_accounting"`
599-
LocationlogCloseOnAccountingStop string `json:"locationlog_close_on_accounting_stop"`
600-
PortalCspSecurityHeaders string `json:"portal_csp_security_headers"`
601-
HashPasswords string `json:"hash_passwords"`
602-
SourceToSendSmsWhenCreatingUsers string `json:"source_to_send_sms_when_creating_users"`
603-
ActiveDirectoryOsJoinCheckBypass string `json:"active_directory_os_join_check_bypass"`
604-
PfperlApiTimeout string `json:"pfperl_api_timeout"`
605-
LdapAttributes []string `json:"ldap_attributes"`
606-
ApiInactivityTimeout int `json:"api_inactivity_timeout"`
607-
ApiMaxExpiration int `json:"api_max_expiration"`
608-
NetFlowOnAllNetworks string `json:"netflow_on_all_networks"`
609-
AccountingTimebucketSize int `json:"accounting_timebucket_size"`
582+
PfconfigMethod string `val:"hash_element"`
583+
PfconfigNS string `val:"config::Pf"`
584+
PfconfigHashNS string `val:"advanced"`
585+
HashingCost string `json:"hashing_cost"`
586+
ScanOnAccounting string `json:"scan_on_accounting"`
587+
PffilterProcesses string `json:"pffilter_processes"`
588+
UpdateIplogWithAccounting string `json:"update_iplog_with_accounting"`
589+
UpdateIplogWithAuthentication string `json:"update_iplog_with_authentication"`
590+
AdminCspSecurityHeaders string `json:"admin_csp_security_headers"`
591+
Multihost string `json:"multihost"`
592+
SsoOnAccessReevaluation string `json:"sso_on_access_reevaluation"`
593+
DisablePfDomainAuth string `json:"disable_pf_domain_auth"`
594+
TimingStatsLevel string `json:"timing_stats_level"`
595+
SsoOnDhcp string `json:"sso_on_dhcp"`
596+
Language string `json:"language"`
597+
StatsdListenPort string `json:"statsd_listen_port"`
598+
SsoOnAccounting string `json:"sso_on_accounting"`
599+
LocationlogCloseOnAccountingStop string `json:"locationlog_close_on_accounting_stop"`
600+
PortalCspSecurityHeaders string `json:"portal_csp_security_headers"`
601+
HashPasswords string `json:"hash_passwords"`
602+
SourceToSendSmsWhenCreatingUsers string `json:"source_to_send_sms_when_creating_users"`
603+
ActiveDirectoryOsJoinCheckBypass string `json:"active_directory_os_join_check_bypass"`
604+
PfperlApiTimeout string `json:"pfperl_api_timeout"`
605+
LdapAttributes []string `json:"ldap_attributes"`
606+
ApiInactivityTimeout int `json:"api_inactivity_timeout"`
607+
ApiMaxExpiration int `json:"api_max_expiration"`
608+
NetFlowOnAllNetworks string `json:"netflow_on_all_networks"`
609+
AccountingTimebucketSize int `json:"accounting_timebucket_size"`
610610
}
611611

612612
type PfConfDns struct {
@@ -967,3 +967,98 @@ type FingerbankSettings struct {
967967
}
968968

969969
var FingerbankConf = FingerbankSettings{}
970+
971+
type PfConfSwitch struct {
972+
StructConfig
973+
PfconfigMethod string `val:"hash_element"`
974+
PfconfigNS string `val:"config::Switch"`
975+
PfconfigHashNS string `val:"-"` // Will be the switch IP
976+
977+
// Basic Information
978+
Type string `json:"type"`
979+
Description string `json:"description"`
980+
Group string `json:"group"`
981+
982+
// VLANs
983+
Vlans map[string]string `json:"vlans"`
984+
VlanMap string `json:"VlanMap"`
985+
986+
// Interfaces
987+
Interfaces map[string]interface{} `json:"interfaces"`
988+
989+
//Roles
990+
Roles map[string]string `json:"roles"`
991+
RoleMap string `json:"RoleMap"`
992+
993+
// Network Related
994+
Networks map[string]interface{} `json:"networks"`
995+
NetworksFrom map[string]interface{} `json:"networks_from"`
996+
997+
// Access Control
998+
AccessLists map[string]interface{} `json:"access_lists"`
999+
AccessListMap string `json:"AccessListMap"`
1000+
ACLsLimit string `json:"ACLsLimit"`
1001+
DownloadableACLsLimit string `json:"DownloadableACLsLimit"`
1002+
UsePushACLs string `json:"UsePushACLs"`
1003+
UseDownloadableACLs string `json:"UseDownloadableACLs"`
1004+
PushACLs string `json:"pushACLs"`
1005+
1006+
// WebAuth
1007+
UrlMap string `json:"UrlMap"`
1008+
Urls map[string]interface{} `json:"urls"`
1009+
ExternalPortalEnforcement string `json:"ExternalPortalEnforcement"`
1010+
1011+
// VPN
1012+
Vpn map[string]interface{} `json:"vpn"`
1013+
VpnMap string `json:"VpnMap"`
1014+
1015+
// MFA
1016+
PostMfaValidation string `json:"PostMfaValidation"`
1017+
1018+
// SNMP
1019+
SNMPUseConnector string `json:"SNMPUseConnector"`
1020+
SNMPVersion string `json:"SNMPVersion"`
1021+
SNMPVersionTrap string `json:"SNMPVersionTrap"`
1022+
SNMPCommunityRead string `json:"SNMPCommunityRead"`
1023+
SNMPCommunityWrite string `json:"SNMPCommunityWrite"`
1024+
SNMPCommunityTrap string `json:"SNMPCommunityTrap"`
1025+
1026+
// CLI
1027+
CliAccess string `json:"cliAccess"`
1028+
CliUser string `json:"cliUser"`
1029+
CliPwd pfcrypt.CryptString `json:"cliPwd"`
1030+
CliEnablePwd pfcrypt.CryptString `json:"cliEnablePwd"`
1031+
CliTransport string `json:"cliTransport"`
1032+
1033+
// Web Services
1034+
WsTransport string `json:"wsTransport"`
1035+
WsUser string `json:"wsUser"`
1036+
WsPwd pfcrypt.CryptString `json:"wsPwd"`
1037+
1038+
// VoIP Detection
1039+
VoIPEnabled int `json:"VoIPEnabled"`
1040+
VoIPCDPDetect string `json:"VoIPCDPDetect"`
1041+
VoIPDHCPDetect string `json:"VoIPDHCPDetect"`
1042+
VoIPLLDPDetect string `json:"VoIPLLDPDetect"`
1043+
1044+
// RADIUS
1045+
UseCoA string `json:"useCoA"`
1046+
RadiusSecret pfcrypt.CryptString `json:"radiusSecret"`
1047+
RadiusDeauthUseConnector string `json:"radiusDeauthUseConnector"`
1048+
1049+
//Advanced
1050+
InlineTrigger []interface{} `json:"inlineTrigger"`
1051+
Mode string `json:"mode"`
1052+
MacSearchesMaxNb string `json:"macSearchesMaxNb"`
1053+
MacSearchesSleepInterval string `json:"macSearchesSleepInterval"`
1054+
DeauthOnPrevious string `json:"deauthOnPrevious"`
1055+
Uplink []string `json:"uplink"`
1056+
}
1057+
1058+
// PfSwitch struct that will help when fetching multiple switch config from config::Switch
1059+
type PfSwitches struct {
1060+
PfconfigKeys
1061+
PfconfigMethod string `val:"keys"`
1062+
PfconfigNS string `val:"config::Switch"`
1063+
Keys []string
1064+
}

0 commit comments

Comments
 (0)