Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

gateways.go 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2014-2015 Edmund Huber
  3. // Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
  4. // released under the MIT license
  5. package irc
  6. import (
  7. "errors"
  8. "fmt"
  9. "net"
  10. "strings"
  11. "github.com/oragono/oragono/irc/passwd"
  12. "github.com/goshuirc/irc-go/ircmsg"
  13. "github.com/oragono/oragono/irc/utils"
  14. )
  15. type webircConfig struct {
  16. PasswordString string `yaml:"password"`
  17. Password []byte `yaml:"password-bytes"`
  18. Fingerprint string
  19. Hosts []string
  20. }
  21. // Populate fills out our password or fingerprint.
  22. func (wc *webircConfig) Populate() (err error) {
  23. if wc.Fingerprint == "" && wc.PasswordString == "" {
  24. return errors.New("Fingerprint or password needs to be specified")
  25. }
  26. if wc.PasswordString != "" {
  27. var password []byte
  28. password, err = passwd.DecodePasswordHash(wc.PasswordString)
  29. wc.Password = password
  30. }
  31. return err
  32. }
  33. func isGatewayAllowed(addr net.Addr, gatewaySpec string) bool {
  34. // "localhost" includes any loopback IP or unix domain socket
  35. if gatewaySpec == "localhost" {
  36. return utils.AddrIsLocal(addr)
  37. }
  38. ip := utils.AddrToIP(addr)
  39. if ip == nil {
  40. return false
  41. }
  42. // exact IP match
  43. if ip.String() == gatewaySpec {
  44. return true
  45. }
  46. // CIDR match
  47. _, gatewayNet, err := net.ParseCIDR(gatewaySpec)
  48. if err != nil {
  49. return false
  50. }
  51. return gatewayNet.Contains(ip)
  52. }
  53. // WEBIRC <password> <gateway> <hostname> <ip> [:flag1 flag2=x flag3]
  54. func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  55. // only allow unregistered clients to use this command
  56. if client.registered || client.proxiedIP != nil {
  57. return false
  58. }
  59. // process flags
  60. var secure bool
  61. if 4 < len(msg.Params) {
  62. for _, x := range strings.Split(msg.Params[4], " ") {
  63. // split into key=value
  64. var key string
  65. if strings.Contains(x, "=") {
  66. y := strings.SplitN(x, "=", 2)
  67. key, _ = y[0], y[1]
  68. } else {
  69. key = x
  70. }
  71. lkey := strings.ToLower(key)
  72. if lkey == "tls" || lkey == "secure" {
  73. // only accept "tls" flag if the gateway's connection to us is secure as well
  74. if client.flags[TLS] || utils.AddrIsLocal(client.socket.conn.RemoteAddr()) {
  75. secure = true
  76. }
  77. }
  78. }
  79. }
  80. for _, info := range server.WebIRCConfig() {
  81. for _, gateway := range info.Hosts {
  82. if isGatewayAllowed(client.socket.conn.RemoteAddr(), gateway) {
  83. // confirm password and/or fingerprint
  84. givenPassword := msg.Params[0]
  85. if 0 < len(info.Password) && passwd.ComparePasswordString(info.Password, givenPassword) != nil {
  86. continue
  87. }
  88. if 0 < len(info.Fingerprint) && client.certfp != info.Fingerprint {
  89. continue
  90. }
  91. proxiedIP := msg.Params[3]
  92. return client.ApplyProxiedIP(proxiedIP, secure)
  93. }
  94. }
  95. }
  96. client.Quit(client.t("WEBIRC command is not usable from your address or incorrect password given"))
  97. return true
  98. }
  99. // PROXY TCP4/6 SOURCEIP DESTIP SOURCEPORT DESTPORT
  100. // http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
  101. func proxyHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  102. // only allow unregistered clients to use this command
  103. if client.registered || client.proxiedIP != nil {
  104. return false
  105. }
  106. for _, gateway := range server.ProxyAllowedFrom() {
  107. if isGatewayAllowed(client.socket.conn.RemoteAddr(), gateway) {
  108. proxiedIP := msg.Params[1]
  109. // assume PROXY connections are always secure
  110. return client.ApplyProxiedIP(proxiedIP, true)
  111. }
  112. }
  113. client.Quit(client.t("PROXY command is not usable from your address"))
  114. return true
  115. }
  116. // ApplyProxiedIP applies the given IP to the client.
  117. func (client *Client) ApplyProxiedIP(proxiedIP string, tls bool) (exiting bool) {
  118. // ensure IP is sane
  119. parsedProxiedIP := net.ParseIP(proxiedIP)
  120. if parsedProxiedIP == nil {
  121. client.Quit(fmt.Sprintf(client.t("Proxied IP address is not valid: [%s]"), proxiedIP))
  122. return true
  123. }
  124. isBanned, banMsg := client.server.checkBans(parsedProxiedIP)
  125. if isBanned {
  126. client.Quit(banMsg)
  127. return true
  128. }
  129. // given IP is sane! override the client's current IP
  130. client.proxiedIP = parsedProxiedIP
  131. client.rawHostname = utils.LookupHostname(proxiedIP)
  132. client.hostname = client.rawHostname
  133. // set tls info
  134. client.certfp = ""
  135. if tls {
  136. client.flags[TLS] = true
  137. } else {
  138. delete(client.flags, TLS)
  139. }
  140. return false
  141. }