Exemple #1
0
        public override async Task DoRequestAsync(ScanRequest request)
        {
            try
            {
                RegistryCredentials credentials = null;

                // if the request was submitted by a user, it must have auth info included
                if (!string.IsNullOrEmpty(request.Authorization))
                {
                    var authResult = authDecoder.AuthenticateAsync(request.Authorization).Result;
                    if (authResult.Succeeded)
                    {
                        credentials = authResult.Principal.ToRegistryCredentials();
                    }
                }
                // if the request came via an event sink, there is no auth provided, and we need to have a default user configured
                else
                {
                    credentials = config.GetCatalogCredentials() ?? throw new ArgumentException("The indexing request had no included authorization, and no default catalog user is configured.");
                }

                if (credentials == null)
                {
                    logger.LogError("Authorization failed for the work item. A token may have expired since it was first submitted.");
                }
                else
                {
                    await authHandler.LoginAsync(credentials);

                    var scope = authHandler.RepoPullScope(request.TargetRepo);
                    if (await authHandler.AuthorizeAsync(scope))
                    {
                        var proxyAuth = authHandler.TokensRequired ? $"Bearer {(await authHandler.GetAuthorizationAsync(scope)).Parameter}" : string.Empty;
                        var client    = clientFactory.GetClient(authHandler);

                        var imageSet = await client.GetImageSetAsync(request.TargetRepo, request.TargetDigest);

                        if ((imageSet?.Images?.Count() ?? 0) != 1)
                        {
                            throw new Exception($"Couldn't find a valid image for {request.TargetRepo}:{request.TargetDigest}");
                        }

                        var scanResult = scanner.GetScan(imageSet.Images.First());
                        if (scanResult == null)
                        {
                            if (request.Submitted)
                            {
                                // we've already submitted this one to the scanner, just sleep on it for a few seconds
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                var host = authHandler.GetRegistryHost();
                                scanner.RequestScan(request.TargetRepo, imageSet.Images.First(), host, proxyAuth);
                                logger.LogInformation($"Submitted {request.TargetRepo}:{request.TargetDigest} to {scanner.GetType().Name} for analysis.");
                                request.Submitted = true;
                            }
                            queue.Push(request);
                        }
                        else
                        {
                            logger.LogInformation($"Got latest {scanner.GetType().Name} scan for {request.TargetRepo}:{request.TargetDigest}");
                        }
                    }
                    else
                    {
                        logger.LogError($"Failed to get pull authorization for {request.TargetRepo}");
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"Processing failed for work item\n {Newtonsoft.Json.JsonConvert.SerializeObject(request)}");
            }
        }
Exemple #2
0
        public async Task <IActionResult> GetSecScanAsync(string repository, string digest)
        {
            if (secScanner == null)
            {
                return(StatusCode(503, "Security scanning is not currently enabled."));
            }

            if (string.IsNullOrEmpty(digest))
            {
                return(BadRequest("An image digest is required."));
            }
            if (!digest.IsDigest())
            {
                return(BadRequest("Digest appears invalid."));
            }

            try
            {
                if (string.IsNullOrEmpty(RegistryCredentials.Registry))
                {
                    return(BadRequest("Session is missing registry information. Try creating a new session."));
                }

                var client   = clientFactory.GetClient(AuthHandler);
                var imageSet = await client.GetImageSetAsync(repository, digest);

                if (imageSet.Images.Count() != 1)
                {
                    return(NotFound("No image was found with the given digest."));
                }

                var scanResult = secScanner.GetScan(imageSet.Images.First());

                if (scanResult == null)
                {
                    secScanner.Queue.TryPush(new Security.ScanRequest
                    {
                        Authorization = Request.Headers["Authorization"],
                        CreatedTime   = DateTime.UtcNow,
                        TargetRepo    = repository,
                        TargetDigest  = digest
                    });
                    return(StatusCode(202, new Security.Result {
                        Status = RequestStatus.Pending
                    }));
                }
                else
                {
                    return(Ok(scanResult));
                }
            }
            catch (RedisConnectionException)
            {
                return(StatusCode(503, "Cannot access cache"));
            }
            catch (HttpRequestException)
            {
                return(StatusCode(503, "Scanner API is not available."));
            }
            catch (Client.NotFoundException)
            {
                return(NotFound());
            }
            catch (Client.AuthenticationException)
            {
                return(Unauthorized());
            }
        }