public static byte[] GenerateMachineID() { // this is steamkit's own implementation, it doesn't match what steamclient does // but this should make it so individual systems can be identified PlatformID platform = Environment.OSVersion.Platform; if (platform == PlatformID.Win32NT) { string hwString = "foobar"; try { RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography"); if (localKey != null) { hwString = localKey.GetValue("MachineGuid").ToString(); } } catch { } try { return(CryptoHelper.SHAHash(Encoding.ASCII.GetBytes(hwString.ToString()))); } catch { return(null); } } else { // todo: implement me! return(null); } }
/// <summary> /// Uploads the actual contents of a file to the UFS. /// The <see cref="UFSClient"/> should be logged on before this point, and the previous request to upload a file must have completed successfully. /// Results are returned in a <see cref="UploadFileFinishedCallback"/>. /// </summary> /// <param name="details">The details to use for uploading the file.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="UploadFileFinishedCallback"/>.</returns> public void UploadFile(UploadDetails details) { const uint MaxBytesPerChunk = 10240; byte[] compressedData = ZipUtil.Compress(details.FileData); byte[] fileHash = CryptoHelper.SHAHash(details.FileData); var buffer = new byte[MaxBytesPerChunk]; using (var ms = new MemoryStream(compressedData)) { for (long readIndex = 0; readIndex < ms.Length; readIndex += buffer.Length) { var msg = new ClientMsgProtobuf <CMsgClientUFSFileChunk>(EMsg.ClientUFSUploadFileChunk); msg.TargetJobID = details.RemoteJobID; var bytesRead = ms.Read(buffer, 0, buffer.Length); if (bytesRead < buffer.Length) { msg.Body.data = buffer.Take(bytesRead).ToArray(); } else { msg.Body.data = buffer; } msg.Body.file_start = ( uint )readIndex; msg.Body.sha_file = fileHash; Send(msg); } } }
async Task <byte[]> DoRawCommandAsync(Server server, HttpMethod method, string command, string data = null, bool doAuth = false, string args = "", string authtoken = null) { var url = BuildCommand(server, command, args, authtoken); var request = new HttpRequestMessage(method, url); if (doAuth && server.Type == "CS") { var req = Interlocked.Increment(ref reqCounter); byte[] shaHash; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { var uri = new Uri(url); bw.Write(sessionId); bw.Write(req); bw.Write(sessionKey); bw.Write(Encoding.UTF8.GetBytes(uri.AbsolutePath)); shaHash = CryptoHelper.SHAHash(ms.ToArray()); } string hexHash = Utils.EncodeHexString(shaHash); string authHeader = string.Format("sessionid={0};req-counter={1};hash={2};", sessionId, req, hexHash); request.Headers.Add("x-steam-auth", authHeader); } if (HttpMethod.Post.Equals(method)) { request.Content = new StringContent(data, Encoding.UTF8); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); } using (var cts = new CancellationTokenSource()) { cts.CancelAfter(RequestTimeout); try { var response = await httpClient.SendAsync(request, cts.Token).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { throw new SteamKitWebRequestException($"Response status code does not indicate success: {response.StatusCode} ({response.ReasonPhrase}).", response); } var responseData = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); return(responseData); } catch (Exception ex) { DebugLog.WriteLine("CDNClient", "Failed to complete web request to {0}: {1}", url, ex.Message); throw; } } }
/// <summary> /// Begins a request to upload a file to the UFS. /// The <see cref="UFSClient"/> should be logged on before this point. /// Results are returned in a <see cref="UploadFileResponseCallback"/>. /// </summary> /// <param name="details">The details to use for uploading the file.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="UploadFileResponseCallback"/>.</returns> public JobID RequestFileUpload(UploadDetails details) { if (details == null) { throw new ArgumentNullException(nameof(details)); } byte[] compressedData = ZipUtil.Compress(details.FileData); var msg = new ClientMsgProtobuf <CMsgClientUFSUploadFileRequest>(EMsg.ClientUFSUploadFileRequest); msg.SourceJobID = steamClient.GetNextJobID(); msg.Body.app_id = details.AppID; msg.Body.can_encrypt = false; msg.Body.file_name = details.FileName; msg.Body.file_size = ( uint )compressedData.Length; msg.Body.raw_file_size = ( uint )details.FileData.Length; msg.Body.sha_file = CryptoHelper.SHAHash(details.FileData); msg.Body.time_stamp = DateUtils.DateTimeToUnixTime(DateTime.UtcNow); Send(msg); return(msg.SourceJobID); }
static string GetMachineGuid() { PlatformID platform = Environment.OSVersion.Platform; if (platform == PlatformID.Win32NT) { // if all else fails, we can at least identify steamkit clients on windows string hwString = "SteamKit"; try { RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography"); if (localKey != null) { hwString = localKey.GetValue("MachineGuid").ToString(); } } catch { } return(GetHexString(CryptoHelper.SHAHash(Encoding.UTF8.GetBytes(hwString)))); } else { // TODO: we need a linux implementation before the machineid requirement is flipped back on return(GetHexString(new byte[] { 0x0 })); } }
/// <summary> /// Request a list of files stored in the cloudfor a target App Id /// Results are returned in a <see cref="DepotKeyCallback"/> callback. /// The returned <see cref="AsyncJob{T}"/> can also be awaited to retrieve the callback result. /// </summary> /// <param name="appid">The AppID to request the file list for.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="DepotKeyCallback"/>.</returns> public AsyncJob <ClientBeginFileUploadCallback> RequestFileUpload(uint appID, string fileName, byte[] fileData, bool compress = false) { byte[] compressedData = compress ? ZipUtil.Compress(fileData) : fileData; var request = new ServiceCallMsgProtobuf <CCloud_ClientBeginFileUpload_Request>(EMsg.ServiceMethodCallFromClient); request.SourceJobID = Client.GetNextJobID(); request.Body.appid = appID; request.Body.is_shared_file = false; request.Body.can_encrypt = true; request.Body.filename = fileName; request.Body.file_size = (uint)compressedData.Length; request.Body.raw_file_size = (uint)fileData.Length; request.Body.file_sha = CryptoHelper.SHAHash(fileData); request.Body.time_stamp = DateUtils.DateTimeToUnixTime(DateTime.UtcNow); request.TargetJobName = SteamCloudServiceJobConstants.ClientBeginFileUpload; lock (_clientBeginFileUploadJobs) { _clientBeginFileUploadJobs.Add(request.SourceJobID); } Client.Send(request); return(new AsyncJob <ClientBeginFileUploadCallback>(Client, request.SourceJobID)); }
static string GetHexString(byte[] data) { data = CryptoHelper.SHAHash(data); return(BitConverter.ToString(data) .Replace("-", "") .ToLower()); }
byte[] DoRawCommand(Server server, string command, string data = null, string method = WebRequestMethods.Http.Get, bool doAuth = false, string args = "") { string url = BuildCommand(server, command, args); using (var webClient = new WebClient()) { webClient.Headers.Clear(); if (doAuth) { reqCounter++; byte[] shaHash; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { var uri = new Uri(url); bw.Write(sessionId); bw.Write(reqCounter); bw.Write(sessionKey); bw.Write(Encoding.ASCII.GetBytes(uri.AbsolutePath)); shaHash = CryptoHelper.SHAHash(ms.ToArray()); } string hexHash = Utils.EncodeHexString(shaHash); string authHeader = string.Format("sessionid={0};req-counter={1};hash={2};", sessionId, reqCounter, hexHash); webClient.Headers["x-steam-auth"] = authHeader; } byte[] resultData = null; if (method == WebRequestMethods.Http.Get) { resultData = webClient.DownloadData(url); } else if (method == WebRequestMethods.Http.Post) { webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; resultData = webClient.UploadData(url, Encoding.ASCII.GetBytes(data)); } return(resultData); } }
/// <summary> /// Request a list of files stored in the cloudfor a target App Id /// Results are returned in a <see cref="DepotKeyCallback"/> callback. /// The returned <see cref="AsyncJob{T}"/> can also be awaited to retrieve the callback result. /// </summary> /// <param name="appid">The AppID to request the file list for.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="DepotKeyCallback"/>.</returns> public AsyncJob <ClientCommitFileUploadCallback> CommitFileUpload(uint appID, string fileName, byte[] fileData, bool succeeded = false) { var request = new ServiceCallMsgProtobuf <CCloud_ClientCommitFileUpload_Request>(EMsg.ServiceMethodCallFromClient); request.SourceJobID = Client.GetNextJobID(); request.Body.appid = appID; request.Body.transfer_succeeded = succeeded; request.Body.filename = fileName; request.Body.file_sha = CryptoHelper.SHAHash(fileData); request.TargetJobName = SteamCloudServiceJobConstants.ClientCommitFileUpload; lock (_clientCommitFileJobs) { _clientCommitFileJobs.Add(request.SourceJobID); } Client.Send(request); return(new AsyncJob <ClientCommitFileUploadCallback>(Client, request.SourceJobID)); }
private void PrepareAuthHeader(ref WebClient client, Uri uri) { reqcounter++; byte[] sha_hash; BinaryWriterEx bb = new BinaryWriterEx(); bb.Write(sessionID); bb.Write(reqcounter); bb.Write(sessionKey); bb.Write(Encoding.ASCII.GetBytes(uri.AbsolutePath)); sha_hash = CryptoHelper.SHAHash(bb.ToArray()); string hex_hash = Utils.EncodeHexString(sha_hash); string authheader = String.Format("sessionid={0};req-counter={1};hash={2};", sessionID, reqcounter, hex_hash); webClient.Headers.Clear(); webClient.Headers.Add("x-steam-auth", authheader); }
public static byte[] GenerateMachineID() { // this is steamkit's own implementation, it doesn't match what steamclient does // but this should make it so individual systems can be identified PlatformID platform = Environment.OSVersion.Platform; if (platform == PlatformID.Win32NT) { StringBuilder hwString = new StringBuilder(); try { using (ManagementClass procClass = new ManagementClass("Win32_Processor")) { foreach (var procObj in procClass.GetInstances()) { hwString.AppendLine(procObj["ProcessorID"].ToString()); } } } catch { } try { using (ManagementClass hdClass = new ManagementClass("Win32_LogicalDisk")) { foreach (var hdObj in hdClass.GetInstances()) { string hdType = hdObj["DriveType"].ToString(); if (hdType != "3") { continue; // only want local disks } hwString.AppendLine(hdObj["VolumeSerialNumber"].ToString()); } } } catch { } try { using (ManagementClass moboClass = new ManagementClass("Win32_BaseBoard")) { foreach (var moboObj in moboClass.GetInstances()) { hwString.AppendLine(moboObj["SerialNumber"].ToString()); } } } catch { } try { return(CryptoHelper.SHAHash(Encoding.ASCII.GetBytes(hwString.ToString()))); } catch { return(null); } } else { // todo: implement me! return(null); } }
byte[] DoRawCommand(Server server, string command, string data = null, string method = WebRequestMethods.Http.Get, bool doAuth = false, string args = "", string authtoken = null) { string url = BuildCommand(server, command, args, authtoken); var webReq = HttpWebRequest.Create(url) as HttpWebRequest; webReq.Method = method; webReq.Pipelined = true; webReq.KeepAlive = true; if (doAuth && server.Type == "CS") { var req = Interlocked.Increment(ref reqCounter); byte[] shaHash; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { var uri = new Uri(url); bw.Write(sessionId); bw.Write(req); bw.Write(sessionKey); bw.Write(Encoding.UTF8.GetBytes(uri.AbsolutePath)); shaHash = CryptoHelper.SHAHash(ms.ToArray()); } string hexHash = Utils.EncodeHexString(shaHash); string authHeader = string.Format("sessionid={0};req-counter={1};hash={2};", sessionId, req, hexHash); webReq.Headers["x-steam-auth"] = authHeader; } if (method == WebRequestMethods.Http.Post) { byte[] payload = Encoding.UTF8.GetBytes(data); webReq.ContentType = "application/x-www-form-urlencoded"; webReq.ContentLength = payload.Length; using (var reqStream = webReq.GetRequestStream()) { reqStream.Write(payload, 0, payload.Length); } } var result = webReq.BeginGetResponse(null, null); if (!result.AsyncWaitHandle.WaitOne(RequestTimeout)) { webReq.Abort(); } try { var response = webReq.EndGetResponse(result); using (var ms = new MemoryStream(( int )response.ContentLength)) { response.GetResponseStream().CopyTo(ms); response.Close(); return(ms.ToArray()); } } catch (Exception ex) { DebugLog.WriteLine("CDNClient", "Failed to complete web request to {0}: {1}", url, ex.Message); throw; } }