A More Secure Internet Connection for Your Home https://fen.gg
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

207 lines
5.8 KiB

  1. package model
  2. //
  3. // Fengg Security Gateway Server Application
  4. // Copyright (C) 2020 Lukas Matt <support@fen.gg>
  5. //
  6. // This program is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. //
  18. import (
  19. "fmt"
  20. "time"
  21. "errors"
  22. "github.com/jmoiron/sqlx"
  23. _ "github.com/lib/pq"
  24. )
  25. const (
  26. NetworkInterfaceNamedInsertTmpl = `
  27. INSERT INTO network_interfaces (
  28. created_at, updated_at, name, network_id, wireless, physical,
  29. bridge_master, bridge_id, tun, default_gateway, gateway_id, link
  30. ) VALUES (
  31. now(), now(), :name, :network_id, :wireless, :physical, :bridge_master,
  32. :bridge_id, :tun, :default_gateway, :gateway_id, :link
  33. ) RETURNING id;`
  34. NetworkInterfaceNamedUpdateTmpl = `
  35. UPDATE network_interfaces
  36. SET updated_at=now(), network_id=:network_id, default_gateway=:default_gateway,
  37. gateway_id=:gateway_id, wireless=:wireless, physical=:physical,
  38. bridge_master=:bridge_master, bridge_id=:bridge_id, tun=:tun, link=:link
  39. WHERE name=:name OR id=:id;`
  40. NetworkInterfaceNamedDeleteTmpl = `DELETE FROM network_interfaces WHERE %s;`
  41. NetworkInterfaceQueryTmpl = `SELECT * FROM network_interfaces %s;`
  42. )
  43. type NetworkInterface struct {
  44. ID uint `db:"id" json:"id"`
  45. CreatedAt time.Time `db:"created_at" json:"createdAt"`
  46. UpdatedAt time.Time `db:"updated_at" json:"updatedAt"`
  47. Name string `db:"name" json:"name"`
  48. DefaultGateway bool `db:"default_gateway" json:"defaultGateway"`
  49. GatewayID *uint `db:"gateway_id" json:"gatewayId,omitempty"`
  50. NetworkID uint `db:"network_id" json:"networkId" binding="required"`
  51. WirelessCard bool `db:"wireless" json:"wirelessCard"`
  52. PhysicalCard bool `db:"physical" json:"physicalCard"`
  53. BridgeMaster bool `db:"bridge_master" json:"bridgeMaster"`
  54. BridgeID *string `db:"bridge_id" json:"bridgeId"`
  55. TunTapDevice bool `db:"tun" json:"tunTapDevice"`
  56. Link bool `db:"link" json:"link"`
  57. }
  58. type NetworkInterfaces []NetworkInterface
  59. func NewNetworkInterface() *NetworkInterface {
  60. return &NetworkInterface{
  61. CreatedAt: time.Now(),
  62. UpdatedAt: time.Now(),
  63. }
  64. }
  65. // FindByNetworkID returns all interfaces related to the given network ID
  66. func (intfs *NetworkInterfaces) FindByNetworkID(id uint) error {
  67. db, err := sqlx.Connect(dbDriver, dbConnect)
  68. if err != nil {
  69. return err
  70. }
  71. defer db.Close()
  72. return db.Select(intfs, fmt.Sprintf(NetworkInterfaceQueryTmpl, "WHERE network_id=$1"), id)
  73. }
  74. // ResetBridgeSetup will remove all bridge related flags from the master and salve interfaces.
  75. func (intf *NetworkInterface) ResetBridgeSetup() error {
  76. if intf.BridgeID == nil {
  77. return errors.New("cannot reset bridge without the bridge_id")
  78. }
  79. db, err := sqlx.Connect(dbDriver, dbConnect)
  80. if err != nil {
  81. return err
  82. }
  83. defer db.Close()
  84. _, err = db.NamedExec(`
  85. UPDATE network_interfaces
  86. SET bridge_master=false, bridge_id=null
  87. WHERE bridge_id=:bridge_id;`, intf)
  88. return err
  89. }
  90. // Network fetches the assigned ip network configuration for the interface
  91. func (intf *NetworkInterface) Network() (network *Network) {
  92. network = &Network{ID: intf.NetworkID}
  93. if !network.Exists() {
  94. logger.Error().Msgf("cannot find network configuration for %s", intf.Name)
  95. return nil
  96. }
  97. return
  98. }
  99. // Exists directly updates the struct with the findings
  100. func (intf *NetworkInterface) Exists() bool {
  101. db, err := sqlx.Connect(dbDriver, dbConnect)
  102. if err != nil {
  103. logger.Error().Err(err).Msg("cannot open database")
  104. return false
  105. }
  106. defer db.Close()
  107. err = db.Get(intf,
  108. fmt.Sprintf(NetworkInterfaceQueryTmpl, "WHERE name=$1 OR id=$2"),
  109. intf.Name, intf.ID)
  110. if err != nil {
  111. logger.Debug().Err(err).Msg("cannot find network_interfaces key or id")
  112. }
  113. return err == nil
  114. }
  115. func (intf *NetworkInterface) Update() error {
  116. db, err := sqlx.Connect(dbDriver, dbConnect)
  117. if err != nil {
  118. return err
  119. }
  120. defer db.Close()
  121. if intf.DefaultGateway {
  122. // only one interface can act as gateway (WAN)
  123. _, err = db.Exec(`
  124. UPDATE network_interfaces
  125. SET default_gateway=false and gateway_id=null;`)
  126. if err != nil {
  127. return err
  128. }
  129. }
  130. _, err = db.NamedExec(NetworkInterfaceNamedUpdateTmpl, intf)
  131. return err
  132. }
  133. func (intf *NetworkInterface) Delete() error {
  134. db, err := sqlx.Connect(dbDriver, dbConnect)
  135. if err != nil {
  136. return err
  137. }
  138. defer db.Close()
  139. _, err = db.NamedExec(fmt.Sprintf(
  140. NetworkInterfaceNamedDeleteTmpl, "name=:name OR id=:id"), intf)
  141. return err
  142. }
  143. func (intf *NetworkInterface) Create() error {
  144. db, err := sqlx.Connect(dbDriver, dbConnect)
  145. if err != nil {
  146. return err
  147. }
  148. defer db.Close()
  149. rows, err := db.NamedQuery(NetworkInterfaceNamedInsertTmpl, intf)
  150. if err != nil {
  151. return err
  152. }
  153. defer rows.Close()
  154. for rows.Next() {
  155. err = rows.Scan(&intf.ID)
  156. if err != nil {
  157. return err
  158. }
  159. }
  160. return nil
  161. }
  162. func (intfs *NetworkInterfaces) FindWirelessCards() error {
  163. db, err := sqlx.Connect(dbDriver, dbConnect)
  164. if err != nil {
  165. return err
  166. }
  167. defer db.Close()
  168. return db.Select(intfs, fmt.Sprintf(NetworkInterfaceQueryTmpl, "WHERE wireless = true"))
  169. }
  170. func (intfs *NetworkInterfaces) FindAll() error {
  171. db, err := sqlx.Connect(dbDriver, dbConnect)
  172. if err != nil {
  173. return err
  174. }
  175. defer db.Close()
  176. return db.Select(intfs, fmt.Sprintf(NetworkInterfaceQueryTmpl, ""))
  177. }