// GetPhotoStatus allows the Eye-Fi card to query the server as to the current uploaded // status of a file. Even more important is that it authenticates the card to the server // by the use of the <credential> field. Essentially if the credential is correct the // server should allow files with the given filesignature to be uploaded. private string GetPhotoStatus(Stream data) { Utilities.Log(" GetPhotoStatus Begin", false); XDocument doc = XDocument.Load(data); EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc); string credentialString = contentHandler.MacAddress + App.ViewModel.EyeFiUploadKey + App.ViewModel.EyeFiServerInstance.ServerNonce; byte[] binaryCredentials = Utilities.HexToBytes(credentialString); string credential = MD5Core.GetHashString(binaryCredentials).ToLower(); if (contentHandler.Credential != credential) { Utilities.Log(" Authentication Error:" + Environment.NewLine + " EyeFi Credential: " + contentHandler.Credential + Environment.NewLine + " App Credential: " + credential, false); return "Authentication error"; } doc = EyeFiSOAPMessages.GetPhotoStatusResponseXML(App.ViewModel.EyeFiFileId); App.ViewModel.EyeFiFileId++; return Utilities.EncodeXml(doc, UTF8Encoding.UTF8); }
// Handles receiving the actual photograph from the card. // data will most likely contain multipart binary post data that needs to be parsed private string UploadPhoto(IRequest request) { Utilities.Log(" UploadPhoto Begin", false); // Parse the multipart/form-data MultiPartDecoder decoder = new MultiPartDecoder(); DecodedData data = decoder.Decode(request.Body, request.ContentType, request.Encoding); // Parse the SOAPENVELOPE using the EyeFiContentHandler() XDocument doc = XDocument.Parse(data.Parameters.Get("SOAPENVELOPE").Value); EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc); // Get the newly uploaded file into memory using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream untrustedFile = new IsolatedStorageFileStream(data.Files["FILENAME"].TempFileName,FileMode.Open,store)) { // Integrity check the file before writing it out string verifiedDigest = EyeFiCrypto.CalculateIntegrityDigest(Utilities.StreamToBytes(untrustedFile), App.ViewModel.EyeFiUploadKey); string unverifiedDigest = data.Parameters.Get("INTEGRITYDIGEST").Value; Utilities.Log(" Comparing my digest [" + verifiedDigest + "] to card's digest [" + unverifiedDigest + "].", false); if (verifiedDigest == unverifiedDigest) { TarArchive tarball = TarArchive.Open(untrustedFile); using (IReader reader = tarball.ExtractAllEntries()) { while (reader.MoveToNextEntry()) { if (!reader.Entry.IsDirectory &! reader.Entry.FilePath.Contains(".log")) { string imageName = (reader.Entry.FilePath).Substring(0, reader.Entry.FilePath.IndexOf('.') + 4); string imagePath = Path.Combine(App.ViewModel.DownloadLocation, imageName); Utilities.Log(" Extracting image to " + imagePath, false); using (IsolatedStorageFileStream image = new IsolatedStorageFileStream(imagePath, FileMode.Create, store)) { reader.WriteEntryTo(image); } NotifyPictureReceived(imagePath); } } } doc = EyeFiSOAPMessages.GetUploadPhotoResponseXML("true"); return Utilities.EncodeXml(doc, UTF8Encoding.UTF8); } else { doc = EyeFiSOAPMessages.GetUploadPhotoResponseXML("false"); return Utilities.EncodeXml(doc, UTF8Encoding.UTF8); } } } }
private string StartSession(Stream data) { Utilities.Log(" StartSession Begin", false); XDocument doc = XDocument.Load(data); EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc); string credentialString = contentHandler.MacAddress + contentHandler.Cnonce + App.ViewModel.EyeFiUploadKey; byte[] binaryCredentials = Utilities.HexToBytes(credentialString); string credential = MD5Core.GetHashString(binaryCredentials).ToLower(); doc = EyeFiSOAPMessages.GetStartSessionResponseXML(credential, App.ViewModel.EyeFiServerInstance.ServerNonce, contentHandler.TransferMode, contentHandler.TransferModeTimeStamp); return Utilities.EncodeXml(doc, UTF8Encoding.UTF8); }