WCF, Net.Tcp endpoint, code-first - web-services

I have a WCF service, this service works perfectly well on a WSHttp endpoint, running as a Windows service under ServiceHost. However I want to move to a TCP endpoint, because of scalability. For the life of me I cannot figure out how to host it correctly. Here is my host's OnStart routine, in VB:
Protected Overrides Sub OnStart(ByVal args() As String)
If _svcHost IsNot Nothing Then
_svcHost.Close()
End If
_svcHost = New ServiceHost(GetType(AutoTestsDataService), New Uri("net.tcp://" & GetIPv4Address() & ":8000"))
Dim metaDataBehavior = _svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)()
If metaDataBehavior Is Nothing Then
_svcHost.Description.Behaviors.Add(New ServiceMetadataBehavior() With {.HttpGetEnabled = False})
Else
metaDataBehavior.HttpGetEnabled = False
End If
_svcHost.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
_svcHost.AddServiceEndpoint(GetType(AutoTestsDataService), New NetTcpBinding(SecurityMode.None, False), ServiceName)
Dim debugBehavior As ServiceDebugBehavior = _svcHost.Description.Behaviors.Find(Of ServiceDebugBehavior)()
If debugBehavior Is Nothing Then
_svcHost.Description.Behaviors.Add(New ServiceDebugBehavior() With {.IncludeExceptionDetailInFaults = My.Settings.flagDebug})
Else
debugBehavior.IncludeExceptionDetailInFaults = My.Settings.flagDebug
End If
Try
_svcHost.Open()
Catch ex As Exception
_svcHost.Abort()
End Try
End Sub
As is, the code compiles fine, installs fine, and the Windows service starts up fine. But there is nothing listening on port 8000. I have made sure the Net.Tcp Listener and Port Sharing services are running properly. I chose to not use the config file at all because I had lots of problems in the past and to me putting code in a config file is bad, nevermind what Microsoft wants me to believe. A code-first implementation is always easier to understand than XML anyways, and to me the above code puts all the right parts in the right places. It just refuses to work. Like I said I can stick with WSHttp, but I would prefer to understand why Net.Tcp is not working.

The best way to determine what the WCF Service listener is doing during startup is to enable WCF Tracing. Therefore, I recommend you configure tracing on the service, which should provide detailed information about any underlying exceptions occurring at startup.
WCF tracing provides diagnostic data for fault monitoring and analysis. You can use tracing instead of a debugger to understand how an application is behaving, or why it faults. You can also correlate faults and processing across components to provide an end-to-end experience, including traces for process milestones across all components of the applications, such as operation calls, code exceptions, warnings and other significant processing events.
http://msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx

The only problem I could see here is the method GetIPv4Address() and what it returns. Usually best choice is to use localhost, host name, or 0.0.0.0.

Related

OpenSSL decryption failed or bad record mac boost::asio

I'm writing a transparent intercepting HTTPS capable proxy using boost::asio + openSSL. I have a default server context where I specify that the server is a TLSv1.2 server, when a client connects, I extract the host from the hello and use SSL_set_SSL_CTX to set the context (which either already exists or I've just created it after spoofing the upstream cert) and initiate the server (downstream) read/write volley as well as the upstream.
This was working before I started storing and sharing contexts. On each new incoming connection, I was creating a new client socket and context, loading ca-bundle as verify file, then creating a new server context, getting the spoofed certificate. It was functioning, but I started developing issues where EC_KEY objects were being double freed and such. I learned from another question of mine that I was going about this the wrong way and began refactoring to recycle and share CTX objects. To be specific, I'm using a single client CTX shared across the board that loads, at program startup, the CA-Bundle for verification.
However, since this refactor, I'm getting this on both the client and the server:
decryption failed or bad record mac
..mixed with a bajillion "short read"s. If I try to force everything TLSv1.2, I get
block cipher pad is wrong
Those errors are given to me after a read/write has failed and I call async_shutdown on either upstream or downstream sockets, which in the callback, error is set (so the shutdown failed).
I've scoured the interwebs finding jira posts from places like apache httpd and nginx where this error was fixed in different ways (resizing read buffers to be larger, openSSL patches, forcing SSLv3, so on and so forth).
I thought there might be an issue with multithreading (my io-service uses a thread pool) but I can see in the code that boost do_init sets locking mechanics for openSSL and all of my IO are wrapped into a single strand.
I'm at a total loss and am wondering if anyone can shed light on what might be happening. I realize I've posted no code, that's because I've got hundreds and hundreds of lines of it and don't want to turn people off with a huge code dump. I realize however this is a rather complicated program and thus a complicated issue so please ask and I'll provide whatever I can.
Edit
I guess I should mention for completeness that I'm getting these errors on both openssl 1.0.2 and 1.0.2a, Win 8.1 x64 and I'm intercepting and routing the http/https traffic through my proxy with with WinDivert.
Edit 2
Reduced entire program to 1 thread, same effect. Created new client CTX for each client connection, same issue. Tried disabling AES-NI, issue persists. Tried different computer, same effect. Recompiled openssl from source (was using precompiled binaries), issue persists. Tried setting additional OP_ workaround flags described in current docs related to downgrade detection, padding bugs, so on and so forth, issue persist. I think I'll just start randomly mashing the keyboard and compile button soon.
I was going to just delete this question, but I decided to answer it in light of the fact that nowhere on the net (that I could find) actually pointed to a correct solution to this problem. I've read every single report about this error that one could find and every single one of those reports, the people "solved" or "reduced" this error in a different way. Every single one of them, a different solution. This is what helped make this issue so difficult to reason out, because everyone everywhere has a different underlying causal explanation.
It's complicated, ready? This error will present itself if you cancel/abort a pending async SSL operation. Mind->boom(). It'll be even more confusing if you do what the docs say and use async_shutdown to do so, because even the call back to async_shutdown will fail (error code is set) and your error message will randomly be something stupid like "decryption failed or bad record mac" or "block cipher pad is wrong" or "SSLv3 alert!" so on and so forth. When seeing errors like this, ignore the errors and analyze the control flow of your IO ops, somewhere you're either prematurely ending them or getting them out of order.
In my case, the premature end was (sort of) intentional, since during this stupid heavy refactor I decided to change things outside the scope of the problem, like my HTTPHeader parser, which I bugged out and ended up cause it to fail nearly 100% and thus aborting the connections. :) The error strings were masking the real cause by telling me encryption failed for some reason or another. Dumb mistake I know, but I take comfort in being the first one (apparently) to recognize it. :)
Open a powershell and type this
(Invoke-WebRequest -Uri status.dev.azure.com).StatusDescription
https://devblogs.microsoft.com/devops/deprecating-weak-cryptographic-standards-tls-1-0-and-1-1-in-azure-devops-services/

C++ server doesn't recognize AS3 socket

Well, three questions in less then 24 hours.But I suppose the lack of any helpful documentation (that i can find anyway) gives me no choice.
now i know all about the security stuff adobes got going, the policy file deal and sandbox limitations that have to be juggled around. ive done the suggested options changes, allowing network access in my AS3 project. I got my server ready to spit the policy file out instantly upon connection; but the problem is flash/AS3 whatever you wanna call it simply doesn't see my server (or the other way around)
AS3 delays for a few seconds, like the documentation say it will if its struggling to make a connection/find the policy file, but it never makes a connection period, tries for a while and then gives up and spits me a access error (because it didn't find the policy file it assumes its not allowed on the network so it get mad at me for trying... lil stubborn buggers)
Flash never gets what its looking for, and my server never detects any connections (failed or succeeded, nothing) I know my server is good because i've tested it with a test client i wrote in C++ and they talk just like best friends.
So I'm pretty much and a loss for ideas now, I thought about re-creating the winsock classes in AS3, but i don't even know how the connect() function fro winsock actually works; i got the declaration, no definition for it that i can find.
I am not sure what you would really need from my source code, but there's over a thousand lines in the client alone already so posting it all isn't really an option. ill give here what i think is relevant at least.
function hwndEnterFrame(e:Event):void
{
//trace("Frame Entered");
if (firstframe)
{
trace("try to reconcile policy file...");
//Security.loadPolicyFile("192.168.1.2:843");
TSocket = new Socket("192.168.1.2",843);//must call flush() to send data***
firstframe = false;
}
The Security.loadpolicyfile doesnt seem to do anything as far ive noticed, i get the same msgs with or without it, the code seems to be looking for the policy file at the location specified in the socket declaration. Everything compiles fine, it just ain't doing what i want it do :P everyone else seems to be writing their servers in Perl or Python i haven't found much of an abundance of C++ material, although from what i understand TCP is a universal connection across any platform that supports it (can cross-language without any funny-business)
meh, that what i got for now, if you want other parts of the code (client or sever side, whatever you want) ill stick it up here quick-like.
EDIT:
I found a swf online that i downloaded, it connected fine to the example server that came with it (but that server was written in c sparp so its not much use to me) but it wont connect to my server. So a known good flash client WONT connect to my C++ server, but a C++ client WILL connect to my C++ server. So its clearly somthing on the server side, becuase it dosnt hear any connection whatsoever from the flash apps (mine or the expamle one)
Cheers;
-Tyler
I finally figured it out. I needed to AllowDomian(IPofserver). I thought I had already tried that but apparently not.

How does Delphi web-services work ? ( Adding method in runtime ?? )

I've created web-service in Delphi XE using WSDL importer.
Delphi generated for me module ITransmitter1.pas with
ITransmitter interface and GetITransmitter function.
To use webservice i use:
var Transmitter: ITransmitter;
begin
Transmitter := GetITransmitter(True, '', nil);
Transmitter.Transmit(Memo1.Text, OutXML);
end;
But i cant see anywhere body of method Transmit ...
In ITransmitter.pas i see:
InvRegistry.RegisterInterface(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter', 'utf-8');
InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter#Transmit');
If i comment this lines i get "interface not supported" error.
As i see here delphi is adding method in RunTime !
How does it work ? Can i add method in runtime to my own class ?
If you created a web service client with the WSDL importer, the generated client code will invoke a method on the server. So in fact, the method 'body' (code) is on the web service server.
Delphi generates a Soap request based on the WSDL, and behind the scenes RTTI (introspection) is used to generate parameters etc. of the web service call as XML. This XML is sent to the server, which executes the method implementation and sends back a Soap response.
Things are opposite if you create the web service server, in this case the Delphi application of course needs to implement all method bodies.
You're in fact calling a method defined in a Interface, which in turn inherits from IInvokable, declared in System.pas.
If you check your source code you'll note that no local object in your project implements the IInvokable interface you're calling, that's because that method is remotely executed in the server.
Before that occurs, there's some pascal code used to create a proper SOAP request to the server, send it and then wait and interpret the server response, consider this implementation details. If you're interested in know a bit more how this works, enable the "use debug .dcus" compiler option, so you can debug inside the VCL/RTL.
Then, as usual, use the StepInto (F7) command to ask the debugger to execute the Transmit method step by step... after some assembler in the TRIO.GenericStub method you'll get to the TRIO.Generic method where the packet is prepared and sent.
For a btSOAP binding I'm using to write this response, the relevant part starts at line 943 in the Rio.pas unit:
try
FWebNode.Execute(Req, Resp);
finally
{ Clear Outbound headers }
FHeadersOutBound.Clear;
end;
THTTPReqResp.Execute then uses wininet.dll functions to perform the connection, send and receive of information with the server using.
There are some levels you can go deep with this... how far you want to go will depend on your interests and the great amount of details are far beyond the scope of my answer here... feel free to post more questions with specific tings you're interested in.
I'm not sure about, but details can change between Delphi versions... I'm using Delphi XE right now.

Problems with changing flexmojos to give testing support to air applications

I want to test air applications and air libraries using flexmojos 3.9-SNAPSHOT.
However, although flexmojos does indeed has support for air, it tries to run the swf generated by the build using flash player, and as I need to use air native libraries I wanted to run the tests using adl (AIR debug launcher).
To do this, I cloned flexmojos in github.com to this repository (http://github.com/mi007/flexmojos). I then created a class that created an -app.xml for the TestRunner.swf file that was generated and ran:
adl TestRunner-app.xml
However, before the Test ends, it should call the server in the port 13540 to report something. When that happens, I'm getting the following error:
Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: app:/TestRunner.swf cannot load data from 127.0.0.1:13540.
at org.sonatype.flexmojos.unitestingsupport::ControlSocket/connect()[/Users/rafael/p2d/others/flexmojos/flexmojos-testing/flexmojos-unittest-support/src/main/flex/org/sonatype/flexmojos/unitestingsupport/ControlSocket.as:46]
at org.sonatype.flexmojos.unitestingsupport::TestApplication/runTests()[/Users/rafael/p2d/others/flexmojos/flexmojos-testing/flexmojos-unittest-support/src/main/flex/org/sonatype/flexmojos/unitestingsupport/TestApplication.as:52]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[C:\autobuild\galaga\frameworks\projects\framework\src\mx\core\UIComponent.as:9408]
at mx.core::UIComponent/set initialized()[C:\autobuild\galaga\frameworks\projects\framework\src\mx\core\UIComponent.as:1169]
at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\galaga\frameworks\projects\framework\src\mx\managers\LayoutManager.as:718]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\galaga\frameworks\projects\framework\src\mx\core\UIComponent.as:8733]
at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\galaga\frameworks\projects\framework\src\mx\core\UIComponent.as:8673]
I know that it is calling the server before in port 13539 successfully, because it prints the test results on the console. I also know that it is opening port 13540 because I was able to telnet to it. However, for some reason it is unable to connect from the air application.
Given the circunstances, I have the following questions:
1) Is there any good documentation that I can read to understand how this security framework works? The only documentation that I found was terribly confusing.
2) Does anyone has any ideas or hints about what might be happening?
3) I have read somewhere that flexmojos hacks the security framework so that flex applications can open a socket to localhost without problems during tests. Is there any documentation about how this is done?
Thanks,
You've got very close to the answer in your comment...
You need to add a line to a file in ~/Library/Preferences/Macromedia/Flash Player/#Security/FlashPlayerTrust yourself, covering the swf you want to run. You can do this by hand directly (all files in that folder will be processed) or by using the Flash Player Settings Manager.

Automatically checking for a new version of my application

Trying to honor a feature request from our customers, I'd like that my application, when Internet is available, check on our website if a new version is available.
The problem is that I have no idea about what have to be done on the server side.
I can imagine that my application (developped in C++ using Qt) has to send a request (HTTP ?) to the server, but what is going to respond to this request ? In order to go through firewalls, I guess I'll have to use port 80 ? Is this correct ?
Or, for such a feature, do I have to ask our network admin to open a specific port number through which I'll communicate ?
#pilif : thanks for your detailed answer. There is still something which is unclear for me :
like
http://www.example.com/update?version=1.2.4
Then you can return what ever you want, probably also the download-URL of the installer of the new version.
How do I return something ? Will it be a php or asp page (I know nothing about PHP nor ASP, I have to confess) ? How can I decode the ?version=1.2.4 part in order to return something accordingly ?
I would absolutely recommend to just do a plain HTTP request to your website. Everything else is bound to fail.
I'd make a HTTP GET request to a certain page on your site containing the version of the local application.
like
http://www.example.com/update?version=1.2.4
Then you can return what ever you want, probably also the download-URL of the installer of the new version.
Why not just put a static file with the latest version to the server and let the client decide? Because you may want (or need) to have control over the process. Maybe 1.2 won't be compatible with the server in the future, so you want the server to force the update to 1.3, but the update from 1.2.4 to 1.2.6 could be uncritical, so you might want to present the client with an optional update.
Or you want to have a breakdown over the installed base.
Or whatever. Usually, I've learned it's best to keep as much intelligence on the server, because the server is what you have ultimate control over.
Speaking here with a bit of experience in the field, here's a small preview of what can (and will - trust me) go wrong:
Your Application will be prevented from making HTTP-Requests by the various Personal Firewall applications out there.
A considerable percentage of users won't have the needed permissions to actually get the update process going.
Even if your users have allowed the old version past their personal firewall, said tool will complain because the .EXE has changed and will recommend the user not to allow the new exe to connect (users usually comply with the wishes of their security tool here).
In managed environments, you'll be shot and hanged (not necessarily in that order) for loading executable content from the web and then actually executing it.
So to keep the damage as low as possible,
fail silently when you can't connect to the update server
before updating, make sure that you have write-permission to the install directory and warn the user if you do not, or just don't update at all.
Provide a way for administrators to turn the auto-update off.
It's no fun to do what you are about to do - especially when you deal with non technically inclined users as I had to numerous times.
Pilif answer was good, and I have lots of experience with this too, but I'd like to add something more:
Remember that if you start yourapp.exe, then the "updater" will try to overwrite yourapp.exe with the newest version. Depending upon your operating system and programming environment (you've mentioned C++/QT, I have no experience with those), you will not be able to overwrite yourapp.exe because it will be in use.
What I have done is create a launcher. I have a MyAppLauncher.exe that uses a config file (xml, very simple) to launch the "real exe". Should a new version exist, the Launcher can update the "real exe" because it's not in use, and then relaunch the new version.
Just keep that in mind and you'll be safe.
Martin,
you are absolutely right of course. But I would deliver the launcher with the installer. Or just download the installer, launch it and quit myself as soon as possible. The reason is bugs in the launcher. You would never, ever, want to be dependent on a component you cannot update (or forget to include in the initial drop).
So the payload I distribute with the updating process of my application is just the standard installer, but devoid of any significant UI. Once the client has checked that the installer has a chance of running successfully and once it has downloaded the updater, it runs that and quits itself.
The updater than runs, installs its payload into the original installation directory and restarts the (hopefully updated) application.
Still: The process is hairy and you better think twice before implementing an Auto Update functionality on the Windows Platform when your application has a wide focus of usage.
in php, the thing is easy:
<?php
if (version_compare($_GET['version'], "1.4.0") < 0){
echo "http://www.example.com/update.exe";
}else{
echo "no update";
}
?>
if course you could extend this so the currently available version isn't hard-coded inside the script, but this is just about illustrating the point.
In your application you would have this pseudo code:
result = makeHTTPRequest("http://www.example.com/update?version=" + getExeVersion());
if result != "no update" then
updater = downloadUpdater(result);
ShellExecute(updater);
ExitApplication;
end;
Feel free to extend the "protocol" by specifying something the PHP script could return to tell the client whether it's an important, mandatory update or not.
Or you can add some text to display to the user - maybe containing some information about what's changed.
Your possibilities are quite limitless.
My Qt app just uses QHttp to read tiny XML file off my website that contains the latest version number. If this is greater than the current version number it gives the option to go to the download page. Very simple. Works fine.
I would agree with #Martin and #Pilif's answer, but add;
Consider allowing your end-users to decide if they want to actually install the update there and then, or delay the installation of the update until they've finished using the program.
I don't know the purpose/function of your app but many applications are launched when the user needs to do something specific there and then - nothing more annoying than launching an app and then being told it's found a new version, and you having to wait for it to download, shut down the app and relaunch itself. If your program has other resources that might be updated (reference files, databases etc) the problem gets worse.
We had an EPOS system running in about 400 shops, and initially we thought it would be great to have the program spot updates and download them (using a file containing a version number very similar to the suggestions you have above)... great idea. Until all of the shops started up their systems at around the same time (8:45-8:50am), and our server was hit serving a 20+Mb download to 400 remote servers, which would then update the local software and cause a restart. Chaos - with nobody able to trade for about 10 minutes.
Needless to say that this caused us to subsequently turn off the 'check for updates' feature and redesign it to allow the shops to 'delay' the update until later in the day. :-)
EDIT: And if anyone from ADOBE is reading - for god's sake why does the damn acrobat reader insist on trying to download updates and crap when I just want to fire-it-up to read a document? Isn't it slow enough at starting, and bloated enough, as it is, without wasting a further 20-30 seconds of my life looking for updates every time I want to read a PDF?
DONT THEY USE THEIR OWN SOFTWARE??!!! :-)
On the server you could just have a simple file "latestversion.txt" which contains the version number (and maybe download URL) of the latest version. The client then just needs to read this file using a simple HTTP request (yes, to port 80) to retrieve http://your.web.site/latestversion.txt, which you can then parse to get the version number. This way you don't need any fancy server code --- you just need to add a simple file to your existing website.
if you keep your files in the update directory on example.com, this PHP script should download them for you given the request previously mentioned. (your update would be yourprogram.1.2.4.exe
$version = $_GET['version'];
$filename = "yourprogram" . $version . ".exe";
$filesize = filesize($filename);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: post-check=0, pre-check=0");
header("Content-type: application-download");
header('Content-Length: ' . $filesize);
header('Content-Disposition: attachment; filename="' . basename($filename).'"');
header("Content-Transfer-Encoding: binary");
This makes your web browser think it's downloading an application.
The simplest way to make this happen is to fire an HTTP request using a library like libcurl and make it download an ini or xml file which contains the online version and where a new version would be available online.
After parsing the xml file you can determine if a new version is needed and download the new version with libcurl and install it.
Just put an (XML) file on your server with the version number of the latest version, and a URL to the download the new version from. Your application can then request the XML file, look if the version differs from its own, and take action accordingly.
I think that simple XML file on the server would be sufficient for version checking only purposes.
You would need then only an ftp account on your server and build system that is able to send a file via ftp after it has built a new version. That build system could even put installation files/zip on your website directly!
If you want to keep it really basic, simply upload a version.txt to a webserver, that contains an integer version number. Download that check against the latest version.txt you downloaded and then just download the msi or setup package and run it.
More advanced versions would be to use rss, xml or similar. It would be best to use a third-party library to parse the rss and you could include information that is displayed to your user about changes if you wish to do so.
Basically you just need simple download functionality.
Both these solutions will only require you to access port 80 outgoing from the client side. This should normally not require any changes to firewalls or networking (on the client side) and you simply need to have a internet facing web server (web hosting, colocation or your own server - all would work here).
There are a couple of commercial auto-update solutions available. I'll leave the recommendations for those to others answerers, because I only have experience on the .net side with Click-Once and Updater Application Block (the latter is not continued any more).