public async Task TestWebPersistDelete()
        {
            var testObj = new BlobStorageAuthorizationChallengeProvider(ConfigurationManager.AppSettings[AppSettingsAuthConfig.authorizationChallengeBlobStorageAccount], "$web");

            ACMESharp.ACME.HttpChallenge challenge = new ACMESharp.ACME.HttpChallenge("http", new HttpChallengeAnswer())
            {
                FileContent = "test",
                FilePath    = "/.well-known/acme-challenge/aBAasda234"
            };
            await testObj.PersistsChallengeFile(challenge);

            await testObj.CleanupChallengeFile(challenge);
        }
Example #2
0
        public void TestHandleCreateAndCleanUpFiles()
        {
            var r = new Random();
            var bn = new byte[10];
            var bv = new byte[10];
            r.NextBytes(bn);
            r.NextBytes(bv);
            var rn = BitConverter.ToString(bn);
            var rv = BitConverter.ToString(bv);

            var c = new HttpChallenge(AcmeProtocol.CHALLENGE_TYPE_HTTP, new HttpChallengeAnswer())
            {
                Token = "FOOBAR",
                FileUrl = $"http://foobar.acmetesting.zyborg.io/utest/{rn}",
                FilePath = $"utest/{rn}",
                FileContent = rv,
            };

            var awsParams = new AwsCommonParams();
            awsParams.InitParams(_handlerParams);

            var p = GetProvider();
            using (var h = p.GetHandler(c, _handlerParams))
            {
                var sites = IisChallengeHandler.ListHttpWebSites();
                Assert.IsNotNull(sites);
                var site = sites.First(x => x.SiteName == _handlerParams.WebSiteRef);
                Assert.IsNotNull(site);

                var fullPath = Environment.ExpandEnvironmentVariables(
                        Path.Combine(site.SiteRoot, c.FilePath));

                // Assert test file does not exist
                Assert.IsFalse(File.Exists(fullPath));

                // Create the record...
                h.Handle(c);

                // ...and assert it does exist
                Assert.IsTrue(File.Exists(fullPath));
                Assert.AreEqual(c.FileContent, File.ReadAllText(fullPath));

                // Clean up the record...
                h.CleanUp(c);

                // ...and assert it does not exist once more
                Assert.IsFalse(File.Exists(fullPath));
            }
        }
        private void EditFile(HttpChallenge httpChallenge, bool delete)
        {
            var filePath = httpChallenge.FilePath;

            // We need to strip off any leading '/' in the path or
            // else it creates a path with an empty leading segment
            if (filePath.StartsWith("/"))
                filePath = filePath.Substring(1);

            using (var s3 = new Amazon.S3.AmazonS3Client(
                    CommonParams.ResolveCredentials(),
                    CommonParams.RegionEndpoint))
            {
                if (delete)
                {
                    var s3Requ = new Amazon.S3.Model.DeleteObjectRequest
                    {
                        BucketName = BucketName,
                        Key = filePath,
                    };
                    var s3Resp = s3.DeleteObject(s3Requ);
                }
                else
                {
                    var s3Requ = new Amazon.S3.Model.PutObjectRequest
                    {
                        BucketName = BucketName,
                        Key = filePath,
                        ContentBody = httpChallenge.FileContent,
                        ContentType = ContentType,
                        CannedACL = S3CannedAcl,
                    };
                    var s3Resp = s3.PutObject(s3Requ);
                }
            }
        }
Example #4
0
        private void EditFile(HttpChallenge httpChallenge, bool delete)
        {
            IisWebSiteBinding site = IisHelper.ResolveSingleSite(WebSiteRef,
                    IisHelper.ListDistinctHttpWebSites());

            var siteRoot = site.SiteRoot;
            if (!string.IsNullOrEmpty(OverrideSiteRoot))
                siteRoot = OverrideSiteRoot;
            if (string.IsNullOrEmpty(siteRoot))
                throw new InvalidOperationException("missing root path for resolve site")
                        .With(nameof(IisWebSiteBinding.SiteId), site.SiteId)
                        .With(nameof(IisWebSiteBinding.SiteName), site.SiteName);

            // IIS-configured Site Root can use env vars
            siteRoot = Environment.ExpandEnvironmentVariables(siteRoot);

            // Make sure we're using the canonical full path
            siteRoot = Path.GetFullPath(siteRoot);

            // We need to strip off any leading '/' in the path
            var filePath = httpChallenge.FilePath;
            if (filePath.StartsWith("/"))
                filePath = filePath.Substring(1);

            var fullFilePath = Path.Combine(siteRoot, filePath);
            var fullDirPath = Path.GetDirectoryName(fullFilePath);
            var fullConfigPath = Path.Combine(fullDirPath, "web.config");

            // This meta-data file will be placed next to the actual
            // Challenge answer content file and it captures some details
            // that we need in order to properly clean up the handling of
            // this Challenge after it has been submitted
            var fullMetaPath = $"{fullFilePath}-acmesharp_meta";

            // Check if user is running with elevated privs and warn if not
            if (!IisHelper.IsAdministrator())
            {
                Console.Error.WriteLine("WARNING:  You are not running with elelvated privileges.");
                Console.Error.WriteLine("          Write access may be denied to the destination.");
            }

            if (delete)
            {
                bool skipLocalWebConfig = SkipLocalWebConfig;
                List<string> dirsCreated = null;

                // First see if there's a meta file there to help us out
                if (File.Exists(fullMetaPath))
                {
                    var meta = JsonHelper.Load<IisChallengeHandlerMeta>(
                            File.ReadAllText(fullMetaPath));

                    skipLocalWebConfig = meta.SkippedLocalWebConfig;
                    dirsCreated = meta.DirsCreated;
                }

                // Get rid of the Challenge answer content file
                if (File.Exists(fullFilePath))
                    File.Delete(fullFilePath);

                // Get rid of web.config if necessary
                if (!skipLocalWebConfig && File.Exists(fullConfigPath))
                    File.Delete(fullConfigPath);

                // Get rid of the meta file so that we can clean up the dirs
                if (File.Exists(fullMetaPath))
                    File.Delete(fullMetaPath);

                // Walk up the tree if needed
                if (dirsCreated?.Count > 0)
                {
                    dirsCreated.Reverse();
                    foreach (var dir in dirsCreated)
                    {
                        if (Directory.Exists(dir))
                        {
                            if (Directory.GetFileSystemEntries(dir).Length == 0)
                            {
                                Directory.Delete(dir);
                            }
                        }
                    }
                }
            }
            else
            {
                // Figure out which dirs we have to create so
                // we can capture and clean it up later on
                var meta = new IisChallengeHandlerMeta
                {
                    WasAdmin = IisHelper.IsAdministrator(),
                    SkippedLocalWebConfig = SkipLocalWebConfig,
                    DirsCreated = new List<string>(),
                };

                // In theory this ascending of the dir path should work
                // just fine, but just in case, this path segment counter
                // should gaurd against the possibility of an infinite loop
                var dirLimit = 100;

                var testDir = fullDirPath;
                while (!Directory.Exists(testDir))
                {
                    // Sanity check against an infinite loop
                    if (--dirLimit <= 0)
                        throw new Exception("Unexpected directory path segment count reached")
                                .With(nameof(dirLimit), "100")
                                .With(nameof(fullDirPath), fullDirPath)
                                .With(nameof(testDir), testDir)
                                .With($"first-{nameof(meta.DirsCreated)}",
                                        meta.DirsCreated[0])
                                .With($"last-{nameof(meta.DirsCreated)}",
                                        meta.DirsCreated[meta.DirsCreated.Count - 1]);

                    if (Path.GetFullPath(testDir) == siteRoot)
                        break;

                    // Add to the top of the list
                    meta.DirsCreated.Insert(0, testDir);
                    // Move to the parent
                    testDir = Path.GetDirectoryName(testDir);
                }

                foreach (var dir in meta.DirsCreated)
                    Directory.CreateDirectory(dir);

                File.WriteAllText(fullFilePath, httpChallenge.FileContent);
                File.WriteAllText(fullMetaPath, JsonHelper.Save(meta));

                if (!SkipLocalWebConfig)
                {
                    var t = typeof(IisChallengeHandler);
                    var r = $"{t.Namespace}.{t.Name}-WebConfig";
                    using (Stream rs = t.Assembly.GetManifestResourceStream(r))
                    {
                        using (var fs = new FileStream(fullConfigPath, FileMode.Create))
                        {
                            rs.CopyTo(fs);
                        }
                    }
                }
            }
        }
Example #5
0
        public void TestHandlerUploadAndCleanUpObject()
        {
            var r = new Random();
            var bn = new byte[10];
            var bv = new byte[10];
            r.NextBytes(bn);
            r.NextBytes(bv);
            var rn = BitConverter.ToString(bn);
            var rv = BitConverter.ToString(bv);

            var c = new HttpChallenge(AcmeProtocol.CHALLENGE_TYPE_HTTP, new HttpChallengeAnswer())
            {
                Token = "FOOBAR",
                FileUrl = $"http://foobar.acmetesting.zyborg.io/utest/{rn}",
                FilePath = $"/utest/{rn}",
                FileContent = rv,
            };

            var awsParams = new AwsCommonParams();
            awsParams.InitParams(_handlerParams);

            var p = GetProvider();
            using (var h = p.GetHandler(c, _handlerParams))
            {
                // Assert test file does not exist
                var s3Obj = AwsS3ChallengeHandler.GetFile(awsParams,
                        _handlerParams.BucketName, c.FilePath);
                
                // Assert test record does *not* exist
                Assert.IsNull(s3Obj);

                // Create the record...
                h.Handle(c);

                // ...and assert it does exist
                s3Obj = AwsS3ChallengeHandler.GetFile(awsParams,
                        _handlerParams.BucketName, c.FilePath);

                Assert.IsNotNull(s3Obj);
                using (var sr = new StreamReader(s3Obj.ResponseStream))
                {
                    var v = sr.ReadToEnd();
                    Assert.AreEqual(c.FileContent, v);
                }

                // Clean up the record...
                h.CleanUp(c);

                // ...and assert it does not exist once more
                s3Obj = AwsS3ChallengeHandler.GetFile(awsParams,
                        _handlerParams.BucketName, c.FilePath);

                Assert.IsNull(s3Obj);
            }
        }