This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

update-he

By: a guest on Nov 15th, 2012  |  syntax: Lua  |  size: 4.92 KB  |  views: 50  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/env lua
  2.  
  3. --[[
  4. Copyright 2010 Jan Bramkamp <crest@tzi.de>. All rights reserved.
  5.  
  6. Redistribution and use in source and binary forms, with or without
  7. modification, are permitted provided that the following conditions are met:
  8.  
  9. 1.      Redistributions of source code must retain the above copyright notice,
  10.         this list of conditions and the following disclaimer.
  11.  
  12. 2.      Redistributions in binary form must reproduce the above copyright
  13.         notice, this list of conditions and the following disclaimer in the
  14.         documentation and/or other materials provided with the distribution.
  15.  
  16. THIS SOFTWARE IS PROVIDED BY Jan Bramkamp ``AS IS'' AND ANY EXPRESS OR
  17. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  19. EVENT SHALL Jan Bramkamp BE LIABLE FOR ANY DIRECT,
  20. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  21. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  24. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  25. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. ]]
  27.  
  28. local io     = require("io")
  29. local socket = require("socket")
  30. local dns    = socket.dns
  31. local http   = require("socket.http")
  32. local ltn12  = require("ltn12")
  33. local ssl    = require("ssl")
  34.  
  35. --------------------------------------------------------------------------------
  36. -- Constants (if you mess with them you're on your own)
  37. --------------------------------------------------------------------------------
  38.  
  39. prefix          = "/usr/local/"
  40. conf_file       = prefix .. "etc/he_update.conf"
  41. cafile          = prefix .. "etc/he.crt"
  42. callback        = function() end
  43. status          = prefix .. "var/db/he.status"
  44. base            = "https://ipv4.tunnelbroker.net/ipv4_end.php"
  45. verify          = { "client_once", "fail_if_no_peer_cert", "peer" }
  46. http_ok         = 200
  47. missing         = "Configuration is incomplete: "
  48.  
  49. --------------------------------------------------------------------------------
  50. -- Configure as needed.
  51. --------------------------------------------------------------------------------
  52.  
  53. function read_config(path)
  54.         local conf = {}
  55.         local err  = ""
  56.        
  57.         function config (c)
  58.                 conf = c
  59.         end
  60.        
  61.         dofile(path)
  62.        
  63.         function miss(msg)
  64.                 err = err .. missing .. msg .. ".\n"
  65.         end
  66.                
  67.         if     conf.cafile   then cafile = conf.cafile          end
  68.         if     conf.status   then status = conf.status          end
  69.         if     conf.callback then callback = conf.callback      end
  70.         if not conf.user     then miss("UserID")                end
  71.         if not conf.ddns     then miss("DDNS domain")           end
  72.         if not conf.pass     then miss("MD5 hashed password")   end
  73.         if not conf.tunnel   then miss("TunnelID of endpoint")  end
  74.        
  75.         if err ~= "" then error(err) end
  76.        
  77.         user    = conf.user
  78.         ddns    = conf.ddns
  79.         pass    = conf.pass
  80.         tunnel  = conf.tunnel
  81.         status  = conf.status
  82. end
  83.  
  84. function read_status(path)
  85.         function current(status)
  86.                 old_ip = tostring(status)
  87.         end
  88.        
  89.         dofile(path)
  90. end
  91.  
  92. function write_status(path, ip)
  93.         local file = assert(io.open(status, "w"), "Failed to open status file.")
  94.         file:write("current(\"" .. ip .. "\")\n")
  95.         file:close()
  96. end
  97.        
  98.  
  99. --------------------------------------------------------------------------------
  100. -- Lookup your endpoint via DNS
  101. --------------------------------------------------------------------------------
  102.  
  103. function lookup()
  104.         new_ip = dns.toip(ddns)
  105.         if new_ip == nil then
  106.                 error("Failed to resolve \"" .. ddns .. "\".")
  107.         end
  108. end
  109.  
  110. --------------------------------------------------------------------------------
  111. -- Build the HTTPS request
  112. --------------------------------------------------------------------------------
  113.  
  114. function inform_he()
  115.         local update = base .. "?ipv4b="     .. new_ip ..
  116.                                "&pass="      .. pass   ..
  117.                                "&user_id="   .. user   ..
  118.                                "&tunnel_id=" .. tunnel
  119.  
  120.         local sink = {}
  121.         local one, code, headers, status = https.request {
  122.                 url    = update,
  123.                 sink   = ltn12.sink.table(sink),
  124.                 cafile = cafile,
  125.                 verify = verify
  126.         }
  127.  
  128.         msg = table.concat(sink)
  129.  
  130.         if code ~= http_ok then -- the request failed.
  131.                 error("HTTPS request failed with code \"" .. code .. "\".")
  132.         end
  133.  
  134.         print(msg)
  135. end
  136.  
  137. function usage()
  138.         error ("Usage: he_update [<config>]\n" ..
  139.                "  <config> defaults to $prefix/etc/he_update.conf")
  140. end
  141.  
  142. function die(exit_code, f)
  143.         local ok, err = pcall(f)
  144.         if not ok then
  145.                 print(err)
  146.                 os.exit(exit_code)
  147.         end
  148. end
  149.  
  150. function get_options()
  151.         if #arg > 1 then
  152.                 usage()
  153.         elseif #arg == 1 then
  154.                 conf_file = arg[1]
  155.         end
  156. end
  157.  
  158. function main()
  159.         die(1, get_options)
  160.         die(2, function() read_config(conf_file) end)
  161.         die(3, lookup)
  162.         die(4, function() read_status(status) end)
  163.        
  164.         if new_ip ~= old_ip then
  165.                 die(5, inform_he)
  166.                 die(6, function() write_status(status, new_ip) end)
  167.                 die(7, callback)
  168.         end
  169. end
  170.  
  171. main()
clone this paste RAW Paste Data