diff options
Diffstat (limited to 'windows/WinUI/APIHandler.cs')
-rw-r--r-- | windows/WinUI/APIHandler.cs | 460 |
1 files changed, 355 insertions, 105 deletions
diff --git a/windows/WinUI/APIHandler.cs b/windows/WinUI/APIHandler.cs index 92b83021..015415c3 100644 --- a/windows/WinUI/APIHandler.cs +++ b/windows/WinUI/APIHandler.cs @@ -7,6 +7,8 @@ using System.Net; using System.IO; using System.Windows; using Newtonsoft.Json; +using System.Diagnostics; +using System.Windows.Threading; namespace WinUI { @@ -18,18 +20,137 @@ namespace WinUI private string url = null; - public APIHandler() + private static volatile APIHandler instance; + private static object syncRoot = new Object(); + + public delegate void NetworkListCallback(List<ZeroTierNetwork> networks); + public delegate void StatusCallback(ZeroTierStatus status); + + private string ZeroTierAddress = ""; + + public static APIHandler Instance + { + get + { + if (instance == null) + { + lock (syncRoot) + { + if (instance == null) + { + if (!initHandler()) + { + return null; + } + } + } + } + + return instance; + } + } + + private static bool initHandler(bool resetToken = false) + { + String localZtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; + String globalZtDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\ZeroTier\\One"; + + String authToken = ""; + Int32 port = 9993; + + if (resetToken) + { + instance = null; + if (File.Exists(localZtDir + "\\authtoken.secret")) + { + File.Delete(localZtDir + "\\authtoken.secret"); + } + + if (File.Exists(localZtDir + "\\zerotier-one.port")) + { + File.Delete(localZtDir + "\\zerotier-one.port"); + } + } + + if (!File.Exists(localZtDir + "\\authtoken.secret") || !File.Exists(localZtDir + "\\zerotier-one.port")) + { + // launch external process to copy file into place + String curPath = System.Reflection.Assembly.GetEntryAssembly().Location; + int index = curPath.LastIndexOf("\\"); + curPath = curPath.Substring(0, index); + ProcessStartInfo startInfo = new ProcessStartInfo(curPath + "\\copyutil.exe", "\""+globalZtDir+"\"" + " " + "\""+localZtDir+"\""); + startInfo.Verb = "runas"; + + + var process = Process.Start(startInfo); + process.WaitForExit(); + } + + authToken = readAuthToken(localZtDir + "\\authtoken.secret"); + + if ((authToken == null) || (authToken.Length <= 0)) + { + MessageBox.Show("Unable to read ZeroTier One authtoken", "ZeroTier One"); + return false; + } + + port = readPort(localZtDir + "\\zerotier-one.port"); + instance = new APIHandler(port, authToken); + return true; + } + + private static String readAuthToken(String path) + { + String authToken = ""; + + if (File.Exists(path)) + { + try + { + byte[] tmp = File.ReadAllBytes(path); + authToken = System.Text.Encoding.UTF8.GetString(tmp).Trim(); + } + catch + { + MessageBox.Show("Unable to read ZeroTier One Auth Token from:\r\n" + path, "ZeroTier One"); + } + } + + return authToken; + } + + private static Int32 readPort(String path) + { + Int32 port = 9993; + + try + { + byte[] tmp = File.ReadAllBytes(path); + port = Int32.Parse(System.Text.Encoding.ASCII.GetString(tmp).Trim()); + if ((port <= 0) || (port > 65535)) + port = 9993; + } + catch + { + } + + return port; + } + + private APIHandler() { url = "http://127.0.0.1:9993"; } public APIHandler(int port, string authtoken) { - url = "http://localhost:" + port; + url = "http://127.0.0.1:" + port; this.authtoken = authtoken; } - public ZeroTierStatus GetStatus() + + + public void GetStatus(StatusCallback cb) { var request = WebRequest.Create(url + "/status" + "?auth=" + authtoken) as HttpWebRequest; if (request != null) @@ -41,136 +162,245 @@ namespace WinUI try { var httpResponse = (HttpWebResponse)request.GetResponse(); - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); - ZeroTierStatus status = null; - try - { - status = JsonConvert.DeserializeObject<ZeroTierStatus>(responseText); - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - return status; - } + ZeroTierStatus status = null; + try + { + status = JsonConvert.DeserializeObject<ZeroTierStatus>(responseText); + + if (ZeroTierAddress != status.Address) + { + ZeroTierAddress = status.Address; + } + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(status); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } } catch (System.Net.Sockets.SocketException) { - return null; + cb(null); } - catch (System.Net.WebException) + catch (System.Net.WebException e) { - return null; + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } } } - public List<ZeroTierNetwork> GetNetworks() + + + public void GetNetworks(NetworkListCallback cb) { var request = WebRequest.Create(url + "/network" + "?auth=" + authtoken) as HttpWebRequest; if (request == null) { - return null; + cb(null); } request.Method = "GET"; request.ContentType = "application/json"; + request.Timeout = 10000; try { var httpResponse = (HttpWebResponse)request.GetResponse(); - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); - List<ZeroTierNetwork> networkList = null; - try - { - networkList = JsonConvert.DeserializeObject<List<ZeroTierNetwork>>(responseText); - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - return networkList; - } + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); + + List<ZeroTierNetwork> networkList = null; + try + { + networkList = JsonConvert.DeserializeObject<List<ZeroTierNetwork>>(responseText); + foreach (ZeroTierNetwork n in networkList) + { + // all networks received via JSON are connected by definition + n.IsConnected = true; + } + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(networkList); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } } catch (System.Net.Sockets.SocketException) { - return null; + cb(null); } - catch (System.Net.WebException) + catch (System.Net.WebException e) { - return null; + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } } } - public void JoinNetwork(string nwid) + public void JoinNetwork(Dispatcher d, string nwid, bool allowManaged = true, bool allowGlobal = false, bool allowDefault = false) { - var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - return; - } + Task.Factory.StartNew(() => + { + var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + return; + } - request.Method = "POST"; + request.Method = "POST"; + request.ContentType = "applicaiton/json"; + request.Timeout = 30000; + try + { + using (var streamWriter = new StreamWriter(((HttpWebRequest)request).GetRequestStream())) + { + string json = "{\"allowManaged\":" + (allowManaged ? "true" : "false") + "," + + "\"allowGlobal\":" + (allowGlobal ? "true" : "false") + "," + + "\"allowDefault\":" + (allowDefault ? "true" : "false") + "}"; + streamWriter.Write(json); + streamWriter.Flush(); + streamWriter.Close(); + } + } + catch (System.Net.WebException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + return; + } - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); - if (httpResponse.StatusCode != HttpStatusCode.OK) - { - Console.WriteLine("Error sending join network message"); - } - } - catch (System.Net.Sockets.SocketException) - { - MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); - } - catch (System.Net.WebException) - { - MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); - } + if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else if (httpResponse.StatusCode != HttpStatusCode.OK) + { + Console.WriteLine("Error sending join network message"); + } + } + catch (System.Net.Sockets.SocketException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); + })); + } + }); } - public void LeaveNetwork(string nwid) + public void LeaveNetwork(Dispatcher d, string nwid) { - var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - return; - } + Task.Factory.StartNew(() => + { + var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; + if (request == null) + { + return; + } - request.Method = "DELETE"; + request.Method = "DELETE"; + request.Timeout = 30000; - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); + try + { + var httpResponse = (HttpWebResponse)request.GetResponse(); - if (httpResponse.StatusCode != HttpStatusCode.OK) - { - Console.WriteLine("Error sending leave network message"); - } - } - catch (System.Net.Sockets.SocketException) - { - MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); - } - catch (System.Net.WebException) - { - MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); - } + if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else if (httpResponse.StatusCode != HttpStatusCode.OK) + { + Console.WriteLine("Error sending leave network message"); + } + } + catch (System.Net.Sockets.SocketException) + { + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); + })); + } + catch (System.Net.WebException e) + { + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + d.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); + })); + } + catch + { + Console.WriteLine("Error leaving network: Unknown error"); + } + }); } - public List<ZeroTierPeer> GetPeers() + public delegate void PeersCallback(List<ZeroTierPeer> peers); + + public void GetPeers(PeersCallback cb) { var request = WebRequest.Create(url + "/peer" + "?auth=" + authtoken) as HttpWebRequest; if (request == null) { - return null; + cb(null); } request.Method = "GET"; @@ -179,30 +409,50 @@ namespace WinUI try { var httpResponse = (HttpWebResponse)request.GetResponse(); - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); - //Console.WriteLine(responseText); - List<ZeroTierPeer> peerList = null; - try - { - peerList = JsonConvert.DeserializeObject<List<ZeroTierPeer>>(responseText); - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - return peerList; - } + if (httpResponse.StatusCode == HttpStatusCode.OK) + { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) + { + var responseText = streamReader.ReadToEnd(); + //Console.WriteLine(responseText); + List<ZeroTierPeer> peerList = null; + try + { + peerList = JsonConvert.DeserializeObject<List<ZeroTierPeer>>(responseText); + } + catch (JsonReaderException e) + { + Console.WriteLine(e.ToString()); + } + cb(peerList); + } + } + else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } } catch (System.Net.Sockets.SocketException) { - return null; + cb(null); } - catch (System.Net.WebException) + catch (System.Net.WebException e) { - return null; + HttpWebResponse res = (HttpWebResponse)e.Response; + if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) + { + APIHandler.initHandler(true); + } + else + { + cb(null); + } } } + + public string NodeAddress() + { + return ZeroTierAddress; + } } } |