Antivirus vs Visual Studio Team Services Agent + SonarQube

En entornos de trabajo corporativo en los que se utiliza TFS como herramienta de desarrollo, el análisis estático de código fuente ayuda a obtener métricas sobre calidad de software, para grandes y pequeños proyectos; un punto de partida en el que comparar convenciones sobre: estilo, seguridad, mantenibilidad, complejidad, duplicidad...

En el caso de las compilaciones lanzadas contra el agente de Visual Studio para Team Services, Microsoft lleva tiempo apostando por el Open Source (suena raro todavía decirlo), la automatización del proceso es sencilla.

Nuestro agente VSTS instalado descargará el código fuente configurado en la compilación, en nuestro caso una de las tareas dentro de este flujo, se integra con el anális de SonarQube mediante su plugin correspondiente. Donde obtenemos repetidamente errores:

Después de comprobar permisos, reinstalar agente, configuración del gateway de conexión TFS-SonarQube el enemigo silencioso... el antivirus, en este caso Panda, detectaba: por un lado el archivo temporal generado por el agente como posible Exploit genérico; por la otra parte, el ejecutable creado durante el análisis de código estático bloqueado...

 

Varias preguntas:

¿Por qué la generación de código fuente desde el agente crea un archivo temporal con el mismo nombre, algún tipo de GUID o similar, en todas las ejecuciones?

¿Por qué la heurística cloud (+hardening) de Panda lo analiza, remite y marca como confiable pero lo sigue bloqueando?

ACTUALIZADO: después de comunicar con Panda se solucionó en la segunda actualización específica para este problema.


Desinstalación manual de SQL Server

Si el método habitual de desinstalación desde el Panel de control resulta imposible, revisamos los registros del desinstalador y seguimos sin poder quitarlo... como último recurso podemos "extirpar":

  1. Desinstalar todos los componentes desde el panel de control, los auxiliares que tiene que ver con SQL, todos los que podamos, aunque nos pregunte que existen dependencias...

  2. Realizar copia de seguridad del registro.
  3. Borrar las siguientes claves:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer

  4. Borrar las referencias a SQL server dentro de la clave:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

  5. Lo mismo para eliminar los servicios: browser, agente, instancias...
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

  6. Renombra las carpetas de instalación:
    C:\Program Files\Microsoft SQL Server
 

Depuración de errores en servicios WCF

Windows Communication Foundation agrega eventos en el registro de Windows de manera predeterminada, por seguridad, depuración, mantenibilidad... es posible utilizar mecanimos adicionales con las trazas.

Añadiendo la siguiente configuración de diagnóstico en nuestro web.config o app.exe.config:

<configuration>  
   <system.diagnostics>  
      <sources>  
            <source name="System.ServiceModel"   
                    switchValue="Information, ActivityTracing"  
                    propagateActivity="true">  
            <listeners>  
               <add name="traceListener"   
                   type="System.Diagnostics.XmlWriterTraceListener"   
                   initializeData= "D:\log\registro.svclog" />  
            </listeners>  
         </source>  
      </sources>  
   </system.diagnostics>  
</configuration>

Posible errores no visibles, dificiles de acotar o reproducir aparecen claros y detallados, hasta el más sencillo que se nos puede pasar por alto:

en System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)
   en WriteresultadoOperacionToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
   en System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   en System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   en System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   en System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   en System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   en System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   en System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
   en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
   en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
   en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
   en System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
   en System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
   en System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
   en System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
   en System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
   en System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
   en System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
   en System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
   en System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.SendReplyCore(Message message, TimeSpan timeout)
   en System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.SendReply(Message message, TimeSpan timeout)
   en System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout)
   en System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout)
   en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc)

Se transforma en algo tal que así:

 

Referencias:

  • Configurando seguimiento: enabling tracing
  • Editor gráfico de configuración WCF: bindings, behaviors, services and diagnostics
    NOTA: la ruta puede variar al ejecutable del SDK según versión, por ejemplo
    C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools

Visual Studio 201X + Fall Creators Update

Lo que a priori puede parecer alarmante, en equipos de desarrollo con Visual Studio instalado, después de instalar la actualización para Windows 10 Fall Creators Update:

[ArgumentOutOfRangeException: El argumento especificado está fuera del intervalo de valores válidos.
Nombre del parámetro: site]
   System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags, PolicyLevel policyLevel, Exception appDomainCreationException) +280

 

Se soluciona sencillamente volviendo a instalar IIS desde el Panel de control\Programas\Programas y características en "Activar o desactivar las características de Windows"

 

Podremos volver a depurar proyectos web en tiempo real sin necesidades de reiniciar. Por algún motivo desconocido durante el proceso se desactiva.

 

Sintaxis en servicios WCF asíncronos

A la hora de generar servicios escalables que aprovechen el procesamiento en paralelo algunos detalles sintácticos deben realizarse literalmente. La nomenclatura puede perderse por el camino generando errores en el momento de ejecutar los servicios:

Your begin method must take an AsyncCallback and an object as the last two arguments and return an IAsyncResult.

Signatura no válida del método Begin asincrónico para el método miFuncionAsyncIniciar en el tipo de XXXX. El método Begin debe tomar AsyncCallback y un objeto como los dos últimos argumentos y devolver IAsyncResult

 

El procedimiento debe tener asociadas la tareas iniciando con el nombre Begin con los dos últimos parámetros AsynCallBack y object:

 

public interface IEjemplo
{

    [OperationContractAttribute]
    string MiFuncion(string mensaje, int otroParametro);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginMiFuncion(string mensaje, int otroParametro, AsyncCallback callback, object asyncState);

    //No se especifica OperationContractAttribute para el método de finalización.
    string EndMiFuncion(IAsyncResult result);

}

La documentación esta clara pero la traducción puede generar confusión con un sencillo erros de sintaxis obligatoria. 

 

How to: Implement an Asynchronous Service Operation

Sessions, Instancing, and Concurrency

 

Ejemplo completo de una excepción tipo:

 

System.InvalidOperationException: Signatura no válida del método Begin asincrónico para el método UnirAsyncIniciar en el tipo de ServiceContract XXXXXX. El método Begin debe tomar AsyncCallback y un objeto como los dos últimos argumentos y devolver IAsyncResult.
   en System.ServiceModel.Description.ServiceReflector.IsBegin(OperationContractAttribute opSettings, MethodInfo method)
   en System.ServiceModel.Description.TypeLoader.CreateOperationDescription(ContractDescription contractDescription, MethodInfo methodInfo, MessageDirection direction, ContractReflectionInfo reflectionInfo, ContractDescription declaringContract)
   en System.ServiceModel.Description.TypeLoader.CreateOperationDescriptions(ContractDescription contractDescription, ContractReflectionInfo reflectionInfo, Type contractToGetMethodsFrom, ContractDescription declaringContract, MessageDirection direction)
   en System.ServiceModel.Description.TypeLoader.CreateContractDescription(ServiceContractAttribute contractAttr, Type contractType, Type serviceType, ContractReflectionInfo& reflectionInfo, Object serviceImplementation)
   en System.ServiceModel.Description.TypeLoader.LoadContractDescriptionHelper(Type contractType, Type serviceType, Object serviceImplementation)
   en System.ServiceModel.Description.ContractDescription.GetContract(Type contractType, Type serviceType)
   en System.ServiceModel.ServiceHost.CreateDescription(IDictionary`2& implementedContracts)
   en System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
   en System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
   en Microsoft.Tools.SvcHost.ServiceHostHelper.CreateServiceHost(Type type, ServiceKind kind)
   en Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)