| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614 |
- //----------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Security
- {
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IdentityModel.Claims;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Runtime;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Diagnostics;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Security.Tokens;
- using System.Net;
- using System.Threading;
- using System.Xml;
- using System.Globalization;
- using System.ServiceModel.Diagnostics.Application;
- // Please use 'sdv //depot/devdiv/private/indigo_xws/ndp/indigo/src/ServiceModel/System/ServiceModel/Security/SecuritySessionChannelFactory.cs'
- // to see version history before the file was renamed
- // This class is named Settings since the only public APIs are for
- // settings; however, this class also manages all functionality
- // for session channels through internal APIs
- static class SecuritySessionClientSettings
- {
- internal const string defaultKeyRenewalIntervalString = "10:00:00";
- internal const string defaultKeyRolloverIntervalString = "00:05:00";
- internal static readonly TimeSpan defaultKeyRenewalInterval = TimeSpan.Parse(defaultKeyRenewalIntervalString, CultureInfo.InvariantCulture);
- internal static readonly TimeSpan defaultKeyRolloverInterval = TimeSpan.Parse(defaultKeyRolloverIntervalString, CultureInfo.InvariantCulture);
- internal const bool defaultTolerateTransportFailures = true;
- }
- sealed class SecuritySessionClientSettings<TChannel> : IChannelSecureConversationSessionSettings, ISecurityCommunicationObject
- {
- SecurityProtocolFactory sessionProtocolFactory;
- TimeSpan keyRenewalInterval;
- TimeSpan keyRolloverInterval;
- bool tolerateTransportFailures;
- SecurityChannelFactory<TChannel> securityChannelFactory;
- IChannelFactory innerChannelFactory;
- ChannelBuilder channelBuilder;
- WrapperSecurityCommunicationObject communicationObject;
- SecurityStandardsManager standardsManager;
- SecurityTokenParameters issuedTokenParameters;
- int issuedTokenRenewalThreshold;
- bool canRenewSession = true;
- object thisLock = new object();
- public SecuritySessionClientSettings()
- {
- this.keyRenewalInterval = SecuritySessionClientSettings.defaultKeyRenewalInterval;
- this.keyRolloverInterval = SecuritySessionClientSettings.defaultKeyRolloverInterval;
- this.tolerateTransportFailures = SecuritySessionClientSettings.defaultTolerateTransportFailures;
- this.communicationObject = new WrapperSecurityCommunicationObject(this);
- }
- IChannelFactory InnerChannelFactory
- {
- get
- {
- return this.innerChannelFactory;
- }
- }
- internal ChannelBuilder ChannelBuilder
- {
- get
- {
- return this.channelBuilder;
- }
- set
- {
- this.channelBuilder = value;
- }
- }
- SecurityChannelFactory<TChannel> SecurityChannelFactory
- {
- get
- {
- return this.securityChannelFactory;
- }
- }
- public SecurityProtocolFactory SessionProtocolFactory
- {
- get
- {
- return this.sessionProtocolFactory;
- }
- set
- {
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.sessionProtocolFactory = value;
- }
- }
- public TimeSpan KeyRenewalInterval
- {
- get
- {
- return this.keyRenewalInterval;
- }
- set
- {
- if (value <= TimeSpan.Zero)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.TimeSpanMustbeGreaterThanTimeSpanZero)));
- }
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.keyRenewalInterval = value;
- }
- }
- public TimeSpan KeyRolloverInterval
- {
- get
- {
- return this.keyRolloverInterval;
- }
- set
- {
- if (value <= TimeSpan.Zero)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.TimeSpanMustbeGreaterThanTimeSpanZero)));
- }
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.keyRolloverInterval = value;
- }
- }
- public bool TolerateTransportFailures
- {
- get
- {
- return this.tolerateTransportFailures;
- }
- set
- {
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.tolerateTransportFailures = value;
- }
- }
- public bool CanRenewSession
- {
- get
- {
- return this.canRenewSession;
- }
- set
- {
- this.canRenewSession = value;
- }
- }
- public SecurityTokenParameters IssuedSecurityTokenParameters
- {
- get
- {
- return this.issuedTokenParameters;
- }
- set
- {
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.issuedTokenParameters = value;
- }
- }
- public SecurityStandardsManager SecurityStandardsManager
- {
- get
- {
- return this.standardsManager;
- }
- set
- {
- this.communicationObject.ThrowIfDisposedOrImmutable();
- this.standardsManager = value;
- }
- }
- // ISecurityCommunicationObject members
- public TimeSpan DefaultOpenTimeout
- {
- get { return ServiceDefaults.OpenTimeout; }
- }
- public TimeSpan DefaultCloseTimeout
- {
- get { return ServiceDefaults.CloseTimeout; }
- }
- internal IChannelFactory CreateInnerChannelFactory()
- {
- if (this.ChannelBuilder.CanBuildChannelFactory<IDuplexSessionChannel>())
- {
- return this.ChannelBuilder.BuildChannelFactory<IDuplexSessionChannel>();
- }
- else if (this.ChannelBuilder.CanBuildChannelFactory<IDuplexChannel>())
- {
- return this.ChannelBuilder.BuildChannelFactory<IDuplexChannel>();
- }
- else if (this.ChannelBuilder.CanBuildChannelFactory<IRequestChannel>())
- {
- return this.ChannelBuilder.BuildChannelFactory<IRequestChannel>();
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- }
- public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return this.communicationObject.BeginClose(timeout, callback, state);
- }
- public void EndClose(IAsyncResult result)
- {
- this.communicationObject.EndClose(result);
- }
- IAsyncResult ISecurityCommunicationObject.OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnClose), timeout, callback, state);
- }
- IAsyncResult ISecurityCommunicationObject.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new OperationWithTimeoutAsyncResult(new OperationWithTimeoutCallback(this.OnOpen), timeout, callback, state);
- }
- public void OnClosed()
- {
- }
- public void OnClosing()
- {
- }
- void ISecurityCommunicationObject.OnEndClose(IAsyncResult result)
- {
- OperationWithTimeoutAsyncResult.End(result);
- }
- void ISecurityCommunicationObject.OnEndOpen(IAsyncResult result)
- {
- OperationWithTimeoutAsyncResult.End(result);
- }
- public void OnFaulted()
- {
- }
- public void OnOpened()
- {
- }
- public void OnOpening()
- {
- }
- public void OnClose(TimeSpan timeout)
- {
- if (this.sessionProtocolFactory != null)
- {
- this.sessionProtocolFactory.Close(false, timeout);
- }
- }
- public void OnAbort()
- {
- if (this.sessionProtocolFactory != null)
- {
- this.sessionProtocolFactory.Close(true, TimeSpan.Zero);
- }
- }
- public void OnOpen(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- if (this.sessionProtocolFactory == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecuritySessionProtocolFactoryShouldBeSetBeforeThisOperation)));
- }
- if (this.standardsManager == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityStandardsManagerNotSet, this.GetType().ToString())));
- }
- if (this.issuedTokenParameters == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.IssuedSecurityTokenParametersNotSet, this.GetType())));
- }
- if (this.keyRenewalInterval < this.keyRolloverInterval)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.KeyRolloverGreaterThanKeyRenewal)));
- }
- this.issuedTokenRenewalThreshold = this.sessionProtocolFactory.SecurityBindingElement.LocalClientSettings.CookieRenewalThresholdPercentage;
- this.ConfigureSessionProtocolFactory();
- this.sessionProtocolFactory.Open(true, timeoutHelper.RemainingTime());
- }
- internal void Close(TimeSpan timeout)
- {
- this.communicationObject.Close(timeout);
- }
- internal void Abort()
- {
- this.communicationObject.Abort();
- }
- internal void Open(SecurityChannelFactory<TChannel> securityChannelFactory,
- IChannelFactory innerChannelFactory, ChannelBuilder channelBuilder, TimeSpan timeout)
- {
- this.securityChannelFactory = securityChannelFactory;
- this.innerChannelFactory = innerChannelFactory;
- this.channelBuilder = channelBuilder;
- this.communicationObject.Open(timeout);
- }
- internal TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via)
- {
- return OnCreateChannel(remoteAddress, via, null);
- }
- internal TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via, MessageFilter filter)
- {
- this.communicationObject.ThrowIfClosed();
- if (filter != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- if (typeof(TChannel) == typeof(IRequestSessionChannel))
- {
- return (TChannel)((object)(new SecurityRequestSessionChannel(this, remoteAddress, via)));
- }
- else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
- {
- // typeof(TChannel) == typeof(IDuplexSessionChannel)
- return (TChannel)((object)(new ClientSecurityDuplexSessionChannel(this, remoteAddress, via)));
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
- }
- }
- void ConfigureSessionProtocolFactory()
- {
- if (this.sessionProtocolFactory is SessionSymmetricMessageSecurityProtocolFactory)
- {
- AddressingVersion addressing = MessageVersion.Default.Addressing;
- if (this.channelBuilder != null)
- {
- MessageEncodingBindingElement encoding = this.channelBuilder.Binding.Elements.Find<MessageEncodingBindingElement>();
- if (encoding != null)
- {
- addressing = encoding.MessageVersion.Addressing;
- }
- }
- if (addressing != AddressingVersion.WSAddressing10 && addressing != AddressingVersion.WSAddressingAugust2004)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, addressing)));
- }
- SessionSymmetricMessageSecurityProtocolFactory symmetric = (SessionSymmetricMessageSecurityProtocolFactory)this.sessionProtocolFactory;
- if (!symmetric.ApplyIntegrity || !symmetric.RequireIntegrity)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecuritySessionRequiresMessageIntegrity)));
- MessagePartSpecification bodyPart = new MessagePartSpecification(true);
- symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction);
- symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseAction);
- symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, addressing.FaultAction);
- symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, addressing.DefaultFaultAction);
- symmetric.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, DotNetSecurityStrings.SecuritySessionFaultAction);
- symmetric.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseAction);
- symmetric.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction);
- if (symmetric.ApplyConfidentiality)
- {
- symmetric.ProtectionRequirements.IncomingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseAction);
- symmetric.ProtectionRequirements.IncomingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction);
- }
- if (symmetric.RequireConfidentiality)
- {
- symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction);
- symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(MessagePartSpecification.NoParts, this.SecurityStandardsManager.SecureConversationDriver.CloseAction);
- symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, addressing.FaultAction);
- symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, addressing.DefaultFaultAction);
- symmetric.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, DotNetSecurityStrings.SecuritySessionFaultAction);
- }
- }
- else if (this.sessionProtocolFactory is SessionSymmetricTransportSecurityProtocolFactory)
- {
- SessionSymmetricTransportSecurityProtocolFactory transport = (SessionSymmetricTransportSecurityProtocolFactory)this.sessionProtocolFactory;
- transport.AddTimestamp = true;
- transport.SecurityTokenParameters.RequireDerivedKeys = false;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- }
- abstract class ClientSecuritySessionChannel : ChannelBase
- {
- EndpointAddress to;
- Uri via;
- IClientReliableChannelBinder channelBinder;
- ChannelParameterCollection channelParameters;
- SecurityToken currentSessionToken;
- SecurityToken previousSessionToken;
- DateTime keyRenewalTime;
- DateTime keyRolloverTime;
- SecurityProtocol securityProtocol;
- SecuritySessionClientSettings<TChannel> settings;
- SecurityTokenProvider sessionTokenProvider;
- bool isKeyRenewalOngoing = false;
- InterruptibleWaitObject keyRenewalCompletedEvent;
- bool sentClose;
- bool receivedClose;
- volatile bool isOutputClosed;
- volatile bool isInputClosed;
- InterruptibleWaitObject inputSessionClosedHandle = new InterruptibleWaitObject(false);
- bool sendCloseHandshake = false;
- MessageVersion messageVersion;
- bool isCompositeDuplexConnection;
- Message closeResponse;
- InterruptibleWaitObject outputSessionCloseHandle = new InterruptibleWaitObject(true);
- WebHeaderCollection webHeaderCollection;
- protected ClientSecuritySessionChannel(SecuritySessionClientSettings<TChannel> settings, EndpointAddress to, Uri via)
- : base(settings.SecurityChannelFactory)
- {
- this.settings = settings;
- this.to = to;
- this.via = via;
- this.keyRenewalCompletedEvent = new InterruptibleWaitObject(false);
- this.messageVersion = settings.SecurityChannelFactory.MessageVersion;
- this.channelParameters = new ChannelParameterCollection(this);
- this.InitializeChannelBinder();
- this.webHeaderCollection = new WebHeaderCollection();
- }
- protected SecuritySessionClientSettings<TChannel> Settings
- {
- get
- {
- return this.settings;
- }
- }
- protected IClientReliableChannelBinder ChannelBinder
- {
- get
- {
- return this.channelBinder;
- }
- }
- public EndpointAddress RemoteAddress
- {
- get
- {
- return this.to;
- }
- }
- public Uri Via
- {
- get
- {
- return this.via;
- }
- }
- protected bool SendCloseHandshake
- {
- get
- {
- return this.sendCloseHandshake;
- }
- }
- protected EndpointAddress InternalLocalAddress
- {
- get
- {
- if (this.channelBinder != null)
- return this.channelBinder.LocalAddress;
- return null;
- }
- }
- protected virtual bool CanDoSecurityCorrelation
- {
- get
- {
- return false;
- }
- }
- public MessageVersion MessageVersion
- {
- get { return this.messageVersion; }
- }
- protected bool IsInputClosed
- {
- get { return isInputClosed; }
- }
- protected bool IsOutputClosed
- {
- get { return isOutputClosed; }
- }
- protected abstract bool ExpectClose
- {
- get;
- }
- protected abstract string SessionId
- {
- get;
- }
- public override T GetProperty<T>()
- {
- if (typeof(T) == typeof(ChannelParameterCollection))
- {
- return this.channelParameters as T;
- }
- if (typeof(T) == typeof(FaultConverter) && (this.channelBinder != null))
- {
- return new SecurityChannelFaultConverter(this.channelBinder.Channel) as T;
- }
- else if (typeof(T) == typeof(WebHeaderCollection))
- {
- return (T)(object)this.webHeaderCollection;
- }
- T result = base.GetProperty<T>();
- if ((result == null) && (channelBinder != null) && (channelBinder.Channel != null))
- {
- result = channelBinder.Channel.GetProperty<T>();
- }
- return result;
- }
- protected abstract void InitializeSession(SecurityToken sessionToken);
- void InitializeSecurityState(SecurityToken sessionToken)
- {
- InitializeSession(sessionToken);
- this.currentSessionToken = sessionToken;
- this.previousSessionToken = null;
- List<SecurityToken> incomingSessionTokens = new List<SecurityToken>(1);
- incomingSessionTokens.Add(sessionToken);
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIdentityCheckAuthenticator(new GenericXmlSecurityTokenAuthenticator());
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIncomingSessionTokens(incomingSessionTokens);
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetOutgoingSessionToken(sessionToken);
- if (this.CanDoSecurityCorrelation)
- {
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).ReturnCorrelationState = true;
- }
- this.keyRenewalTime = GetKeyRenewalTime(sessionToken);
- }
- void SetupSessionTokenProvider()
- {
- InitiatorServiceModelSecurityTokenRequirement requirement = new InitiatorServiceModelSecurityTokenRequirement();
- this.Settings.IssuedSecurityTokenParameters.InitializeSecurityTokenRequirement(requirement);
- requirement.KeyUsage = SecurityKeyUsage.Signature;
- requirement.SupportSecurityContextCancellation = true;
- requirement.SecurityAlgorithmSuite = this.Settings.SessionProtocolFactory.OutgoingAlgorithmSuite;
- requirement.SecurityBindingElement = this.Settings.SessionProtocolFactory.SecurityBindingElement;
- requirement.TargetAddress = this.to;
- requirement.Via = this.Via;
- requirement.MessageSecurityVersion = this.Settings.SessionProtocolFactory.MessageSecurityVersion.SecurityTokenVersion;
- requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeUriProperty] = this.Settings.SessionProtocolFactory.PrivacyNoticeUri;
- requirement.WebHeaders = this.webHeaderCollection;
- if (this.channelParameters != null)
- {
- requirement.Properties[ServiceModelSecurityTokenRequirement.ChannelParametersCollectionProperty] = this.channelParameters;
- }
- requirement.Properties[ServiceModelSecurityTokenRequirement.PrivacyNoticeVersionProperty] = this.Settings.SessionProtocolFactory.PrivacyNoticeVersion;
- if (this.channelBinder.LocalAddress != null)
- {
- requirement.DuplexClientLocalAddress = this.channelBinder.LocalAddress;
- }
- this.sessionTokenProvider = this.Settings.SessionProtocolFactory.SecurityTokenManager.CreateSecurityTokenProvider(requirement);
- }
- void OpenCore(SecurityToken sessionToken, TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- this.securityProtocol = this.Settings.SessionProtocolFactory.CreateSecurityProtocol(this.to, this.Via, null, true, timeoutHelper.RemainingTime());
- if (!(this.securityProtocol is IInitiatorSecuritySessionProtocol))
- {
- Fx.Assert("Security protocol must be IInitiatorSecuritySessionProtocol.");
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProtocolMisMatch, "IInitiatorSecuritySessionProtocol", this.GetType().ToString())));
- }
- this.securityProtocol.Open(timeoutHelper.RemainingTime());
- this.channelBinder.Open(timeoutHelper.RemainingTime());
- this.InitializeSecurityState(sessionToken);
- }
- protected override void OnFaulted()
- {
- this.AbortCore();
- this.inputSessionClosedHandle.Fault(this);
- this.keyRenewalCompletedEvent.Fault(this);
- this.outputSessionCloseHandle.Fault(this);
- base.OnFaulted();
- }
- protected override void OnOpen(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- SetupSessionTokenProvider();
- SecurityUtils.OpenTokenProviderIfRequired(this.sessionTokenProvider, timeoutHelper.RemainingTime());
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateBoundedActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecuritySetup), ActivityType.SecuritySetup);
- }
- SecurityToken sessionToken = this.sessionTokenProvider.GetToken(timeoutHelper.RemainingTime());
- // Token was issued, do send cancel on close;
- this.sendCloseHandshake = true;
- this.OpenCore(sessionToken, timeoutHelper.RemainingTime());
- }
- }
- protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
- {
- ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateAsyncActivity() : null;
- using (ServiceModelActivity.BoundOperation(activity, true))
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecuritySetup), ActivityType.SecuritySetup);
- }
- return new OpenAsyncResult(this, timeout, callback, state);
- }
- }
- protected override void OnEndOpen(IAsyncResult result)
- {
- OpenAsyncResult.End(result);
- }
- void InitializeChannelBinder()
- {
- ChannelBuilder channelBuilder = this.Settings.ChannelBuilder;
- TolerateFaultsMode faultMode = this.Settings.TolerateTransportFailures ? TolerateFaultsMode.Always : TolerateFaultsMode.Never;
- if (channelBuilder.CanBuildChannelFactory<IDuplexSessionChannel>())
- {
- this.channelBinder = ClientReliableChannelBinder<IDuplexSessionChannel>.CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory<IDuplexSessionChannel>)(object)this.Settings.InnerChannelFactory,
- MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout);
- }
- else if (channelBuilder.CanBuildChannelFactory<IDuplexChannel>())
- {
- this.channelBinder = ClientReliableChannelBinder<IDuplexChannel>.CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory<IDuplexChannel>)(object)this.Settings.InnerChannelFactory,
- MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout);
- this.isCompositeDuplexConnection = true;
- }
- else if (channelBuilder.CanBuildChannelFactory<IRequestChannel>())
- {
- this.channelBinder = ClientReliableChannelBinder<IRequestChannel>.CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory<IRequestChannel>)(object)this.Settings.InnerChannelFactory,
- MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout);
- }
- else if (channelBuilder.CanBuildChannelFactory<IRequestSessionChannel>())
- {
- this.channelBinder = ClientReliableChannelBinder<IRequestSessionChannel>.CreateBinder(this.RemoteAddress, this.Via, (IChannelFactory<IRequestSessionChannel>)(object)this.Settings.InnerChannelFactory,
- MaskingMode.None, faultMode, this.channelParameters, this.DefaultCloseTimeout, this.DefaultSendTimeout);
- }
- this.channelBinder.Faulted += this.OnInnerFaulted;
- }
- void OnInnerFaulted(IReliableChannelBinder sender, Exception exception)
- {
- this.Fault(exception);
- }
- protected virtual bool OnCloseResponseReceived()
- {
- bool setInputSessionClosedHandle = false;
- bool isCloseResponseExpected = false;
- lock (ThisLock)
- {
- isCloseResponseExpected = this.sentClose;
- if (isCloseResponseExpected && !this.isInputClosed)
- {
- this.isInputClosed = true;
- setInputSessionClosedHandle = true;
- }
- }
- if (!isCloseResponseExpected)
- {
- this.Fault(new ProtocolException(SR.GetString(SR.UnexpectedSecuritySessionCloseResponse)));
- return false;
- }
- if (setInputSessionClosedHandle)
- {
- this.inputSessionClosedHandle.Set();
- }
- return true;
- }
- protected virtual bool OnCloseReceived()
- {
- if (!ExpectClose)
- {
- this.Fault(new ProtocolException(SR.GetString(SR.UnexpectedSecuritySessionClose)));
- return false;
- }
- bool setInputSessionClosedHandle = false;
- lock (ThisLock)
- {
- if (!this.isInputClosed)
- {
- this.isInputClosed = true;
- this.receivedClose = true;
- setInputSessionClosedHandle = true;
- }
- }
- if (setInputSessionClosedHandle)
- {
- this.inputSessionClosedHandle.Set();
- }
- return true;
- }
- Message PrepareCloseMessage()
- {
- SecurityToken tokenToClose;
- lock (ThisLock)
- {
- tokenToClose = this.currentSessionToken;
- }
- RequestSecurityToken rst = new RequestSecurityToken(this.Settings.SecurityStandardsManager);
- rst.RequestType = this.Settings.SecurityStandardsManager.TrustDriver.RequestTypeClose;
- rst.CloseTarget = this.Settings.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(tokenToClose, SecurityTokenReferenceStyle.External);
- rst.MakeReadOnly();
- Message closeMessage = Message.CreateMessage(this.MessageVersion, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseAction, this.MessageVersion.Addressing), rst);
- RequestReplyCorrelator.PrepareRequest(closeMessage);
- if (this.webHeaderCollection != null && this.webHeaderCollection.Count > 0)
- {
- object prop = null;
- HttpRequestMessageProperty rmp = null;
- if (closeMessage.Properties.TryGetValue(HttpRequestMessageProperty.Name, out prop))
- {
- rmp = prop as HttpRequestMessageProperty;
- }
- else
- {
- rmp = new HttpRequestMessageProperty();
- closeMessage.Properties.Add(HttpRequestMessageProperty.Name, rmp);
- }
- if (rmp != null && rmp.Headers != null)
- {
- rmp.Headers.Add(this.webHeaderCollection);
- }
- }
- if (this.InternalLocalAddress != null)
- {
- closeMessage.Headers.ReplyTo = this.InternalLocalAddress;
- }
- else
- {
- if (closeMessage.Version.Addressing == AddressingVersion.WSAddressing10)
- {
- closeMessage.Headers.ReplyTo = null;
- }
- else if (closeMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
- {
- closeMessage.Headers.ReplyTo = EndpointAddress.AnonymousAddress;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, closeMessage.Version.Addressing)));
- }
- }
- if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity)
- {
- TraceUtility.AddAmbientActivityToMessage(closeMessage);
- }
- return closeMessage;
- }
- protected SecurityProtocolCorrelationState SendCloseMessage(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- SecurityProtocolCorrelationState closeCorrelationState;
- Message closeMessage = PrepareCloseMessage();
- try
- {
- closeCorrelationState = this.securityProtocol.SecureOutgoingMessage(ref closeMessage, timeoutHelper.RemainingTime(), null);
- this.ChannelBinder.Send(closeMessage, timeoutHelper.RemainingTime());
- }
- finally
- {
- closeMessage.Close();
- }
- SecurityTraceRecordHelper.TraceCloseMessageSent(this.currentSessionToken, this.RemoteAddress);
- return closeCorrelationState;
- }
- protected void SendCloseResponseMessage(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- Message message = null;
- try
- {
- message = this.closeResponse;
- this.securityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime(), null);
- this.ChannelBinder.Send(message, timeoutHelper.RemainingTime());
- SecurityTraceRecordHelper.TraceCloseResponseMessageSent(this.currentSessionToken, this.RemoteAddress);
- }
- finally
- {
- message.Close();
- }
- }
- IAsyncResult BeginSendCloseMessage(TimeSpan timeout, AsyncCallback callback, object state)
- {
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateBoundedActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup);
- }
- Message closeMessage = PrepareCloseMessage();
- return new SecureSendAsyncResult(closeMessage, this, timeout, callback, state, true);
- }
- }
- SecurityProtocolCorrelationState EndSendCloseMessage(IAsyncResult result)
- {
- SecurityProtocolCorrelationState correlationState = SecureSendAsyncResult.End(result);
- SecurityTraceRecordHelper.TraceCloseMessageSent(this.currentSessionToken, this.RemoteAddress);
- return correlationState;
- }
- IAsyncResult BeginSendCloseResponseMessage(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new SecureSendAsyncResult(this.closeResponse, this, timeout, callback, state, true);
- }
- void EndSendCloseResponseMessage(IAsyncResult result)
- {
- SecureSendAsyncResult.End(result);
- SecurityTraceRecordHelper.TraceCloseResponseMessageSent(this.currentSessionToken, this.RemoteAddress);
- }
- MessageFault GetProtocolFault(ref Message message, out bool isKeyRenewalFault, out bool isSessionAbortedFault)
- {
- isKeyRenewalFault = false;
- isSessionAbortedFault = false;
- MessageFault result = null;
- using (MessageBuffer buffer = message.CreateBufferedCopy(int.MaxValue))
- {
- message = buffer.CreateMessage();
- Message copy = buffer.CreateMessage();
- MessageFault fault = MessageFault.CreateFault(copy, TransportDefaults.MaxSecurityFaultSize);
- if (fault.Code.IsSenderFault)
- {
- FaultCode subCode = fault.Code.SubCode;
- if (subCode != null)
- {
- SecurityStandardsManager standardsManager = this.securityProtocol.SecurityProtocolFactory.StandardsManager;
- SecureConversationDriver scDriver = standardsManager.SecureConversationDriver;
- if (subCode.Namespace == scDriver.Namespace.Value && subCode.Name == scDriver.RenewNeededFaultCode.Value)
- {
- result = fault;
- isKeyRenewalFault = true;
- }
- else if (subCode.Namespace == DotNetSecurityStrings.Namespace && subCode.Name == DotNetSecurityStrings.SecuritySessionAbortedFault)
- {
- result = fault;
- isSessionAbortedFault = true;
- }
- }
- }
- }
- return result;
- }
- void ProcessKeyRenewalFault()
- {
- SecurityTraceRecordHelper.TraceSessionKeyRenewalFault(this.currentSessionToken, this.RemoteAddress);
- lock (ThisLock)
- {
- this.keyRenewalTime = DateTime.UtcNow;
- }
- }
- void ProcessSessionAbortedFault(MessageFault sessionAbortedFault)
- {
- SecurityTraceRecordHelper.TraceRemoteSessionAbortedFault(this.currentSessionToken, this.RemoteAddress);
- this.Fault(new FaultException(sessionAbortedFault));
- }
- void ProcessCloseResponse(Message response)
- {
- // the close message may have been received by the channel after the channel factory has been closed
- if (response.Headers.Action != this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction.Value)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.InvalidCloseResponseAction, response.Headers.Action)), response);
- }
- RequestSecurityTokenResponse rstr = null;
- XmlDictionaryReader bodyReader = response.GetReaderAtBodyContents();
- using (bodyReader)
- {
- if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
- rstr = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityTokenResponse(bodyReader);
- else if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
- {
- RequestSecurityTokenResponseCollection rstrc = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader);
- foreach (RequestSecurityTokenResponse rstrItem in rstrc.RstrCollection)
- {
- if (rstr != null)
- {
- // More than one RSTR is found. So throw an exception.
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MoreThanOneRSTRInRSTRC)));
- }
- rstr = rstrItem;
- }
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- response.ReadFromBodyContentsToEnd(bodyReader);
- }
- if (!rstr.IsRequestedTokenClosed)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SessionTokenWasNotClosed)), response);
- }
- }
- void PrepareReply(Message request, Message reply)
- {
- if (request.Headers.ReplyTo != null)
- {
- request.Headers.ReplyTo.ApplyTo(reply);
- }
- else if (request.Headers.From != null)
- {
- request.Headers.From.ApplyTo(reply);
- }
- if (request.Headers.MessageId != null)
- {
- reply.Headers.RelatesTo = request.Headers.MessageId;
- }
- TraceUtility.CopyActivity(request, reply);
- if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity)
- {
- TraceUtility.AddActivityHeader(reply);
- }
- }
- bool DoesSkiClauseMatchSigningToken(SecurityContextKeyIdentifierClause skiClause, Message request)
- {
- if (this.SessionId == null)
- {
- return false;
- }
- return (skiClause.ContextId.ToString() == this.SessionId);
- }
- void ProcessCloseMessage(Message message)
- {
- RequestSecurityToken rst;
- XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
- using (bodyReader)
- {
- rst = this.Settings.SecurityStandardsManager.TrustDriver.CreateRequestSecurityToken(bodyReader);
- message.ReadFromBodyContentsToEnd(bodyReader);
- }
- if (rst.RequestType != null && rst.RequestType != this.Settings.SecurityStandardsManager.TrustDriver.RequestTypeClose)
- {
- throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.InvalidRstRequestType, rst.RequestType)), message);
- }
- if (rst.CloseTarget == null)
- {
- throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.NoCloseTargetSpecified)), message);
- }
- SecurityContextKeyIdentifierClause sctSkiClause = rst.CloseTarget as SecurityContextKeyIdentifierClause;
- if (sctSkiClause == null || !DoesSkiClauseMatchSigningToken(sctSkiClause, message))
- {
- throw TraceUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.BadCloseTarget, rst.CloseTarget)), message);
- }
- // prepare the close response
- RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.Settings.SecurityStandardsManager);
- rstr.Context = rst.Context;
- rstr.IsRequestedTokenClosed = true;
- rstr.MakeReadOnly();
- Message response = null;
- if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
- response = Message.CreateMessage(message.Version, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction, message.Version.Addressing), rstr);
- else if (this.Settings.SecurityStandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
- {
- List<RequestSecurityTokenResponse> rstrList = new List<RequestSecurityTokenResponse>();
- rstrList.Add(rstr);
- RequestSecurityTokenResponseCollection rstrCollection = new RequestSecurityTokenResponseCollection(rstrList, this.Settings.SecurityStandardsManager);
- response = Message.CreateMessage(message.Version, ActionHeader.Create(this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction, message.Version.Addressing), rstrCollection);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- PrepareReply(message, response);
- this.closeResponse = response;
- }
- bool ShouldWrapException(Exception e)
- {
- return ((e is FormatException) || (e is XmlException));
- }
- protected Message ProcessIncomingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, out MessageFault protocolFault)
- {
- protocolFault = null;
- lock (ThisLock)
- {
- DoKeyRolloverIfNeeded();
- }
- try
- {
- VerifyIncomingMessage(ref message, timeout, correlationState);
- string action = message.Headers.Action;
- if (action == this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseResponseAction.Value)
- {
- SecurityTraceRecordHelper.TraceCloseResponseReceived(this.currentSessionToken, this.RemoteAddress);
- this.ProcessCloseResponse(message);
- this.OnCloseResponseReceived();
- }
- else if (action == this.Settings.SecurityStandardsManager.SecureConversationDriver.CloseAction.Value)
- {
- SecurityTraceRecordHelper.TraceCloseMessageReceived(this.currentSessionToken, this.RemoteAddress);
- this.ProcessCloseMessage(message);
- this.OnCloseReceived();
- }
- else if (action == DotNetSecurityStrings.SecuritySessionFaultAction)
- {
- bool isKeyRenewalFault;
- bool isSessionAbortedFault;
- protocolFault = GetProtocolFault(ref message, out isKeyRenewalFault, out isSessionAbortedFault);
- if (isKeyRenewalFault)
- {
- ProcessKeyRenewalFault();
- }
- else if (isSessionAbortedFault)
- {
- ProcessSessionAbortedFault(protocolFault);
- }
- else
- {
- return message;
- }
- }
- else
- {
- return message;
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if ((e is CommunicationException) || (e is TimeoutException) || (Fx.IsFatal(e)) || !ShouldWrapException(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e));
- }
- message.Close();
- return null;
- }
- protected Message ProcessRequestContext(RequestContext requestContext, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
- {
- if (requestContext == null)
- {
- return null;
- }
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- Message message = requestContext.RequestMessage;
- Message unverifiedMessage = message;
- try
- {
- Exception faultException = null;
- try
- {
- MessageFault dummyProtocolFault;
- return ProcessIncomingMessage(message, timeoutHelper.RemainingTime(), correlationState, out dummyProtocolFault);
- }
- catch (MessageSecurityException e)
- {
- // if the message is an unsecured security fault from the other party over the same connection then fault the session
- if (!isCompositeDuplexConnection)
- {
- if (unverifiedMessage.IsFault)
- {
- MessageFault fault = MessageFault.CreateFault(unverifiedMessage, TransportDefaults.MaxSecurityFaultSize);
- if (SecurityUtils.IsSecurityFault(fault, this.settings.sessionProtocolFactory.StandardsManager))
- {
- faultException = SecurityUtils.CreateSecurityFaultException(fault);
- }
- }
- else
- {
- faultException = e;
- }
- }
- }
- if (faultException != null)
- {
- this.Fault(faultException);
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(faultException);
- }
- return null;
- }
- finally
- {
- requestContext.Close(timeoutHelper.RemainingTime());
- }
- }
- /// <summary>
- /// This method removes the previous session key when the key rollover time is past.
- /// It must be called within a lock
- /// </summary>
- void DoKeyRolloverIfNeeded()
- {
- if (DateTime.UtcNow >= this.keyRolloverTime && this.previousSessionToken != null)
- {
- SecurityTraceRecordHelper.TracePreviousSessionKeyDiscarded(this.previousSessionToken, this.currentSessionToken, this.RemoteAddress);
- // forget the previous session token
- this.previousSessionToken = null;
- List<SecurityToken> incomingTokens = new List<SecurityToken>(1);
- incomingTokens.Add(this.currentSessionToken);
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIncomingSessionTokens(incomingTokens);
- }
- }
- DateTime GetKeyRenewalTime(SecurityToken token)
- {
- TimeSpan tokenValidityInterval = TimeSpan.FromTicks((long)(((token.ValidTo.Ticks - token.ValidFrom.Ticks) * this.settings.issuedTokenRenewalThreshold) / 100));
- DateTime keyRenewalTime1 = TimeoutHelper.Add(token.ValidFrom, tokenValidityInterval);
- DateTime keyRenewalTime2 = TimeoutHelper.Add(token.ValidFrom, this.settings.keyRenewalInterval);
- if (keyRenewalTime1 < keyRenewalTime2)
- {
- return keyRenewalTime1;
- }
- else
- {
- return keyRenewalTime2;
- }
- }
- /// <summary>
- /// This method returns true if key renewal is needed.
- /// It must be called within a lock
- /// </summary>
- bool IsKeyRenewalNeeded()
- {
- return DateTime.UtcNow >= this.keyRenewalTime;
- }
- /// <summary>
- /// When the new session token is obtained, mark the current token as previous and remove it
- /// after KeyRolloverTime. Mark the new current as pending and update the next key renewal time
- /// </summary>
- void UpdateSessionTokens(SecurityToken newToken)
- {
- lock (ThisLock)
- {
- this.previousSessionToken = this.currentSessionToken;
- this.keyRolloverTime = TimeoutHelper.Add(DateTime.UtcNow, this.Settings.KeyRolloverInterval);
- this.currentSessionToken = newToken;
- this.keyRenewalTime = GetKeyRenewalTime(newToken);
- List<SecurityToken> incomingTokens = new List<SecurityToken>(2);
- incomingTokens.Add(this.previousSessionToken);
- incomingTokens.Add(this.currentSessionToken);
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetIncomingSessionTokens(incomingTokens);
- ((IInitiatorSecuritySessionProtocol)this.securityProtocol).SetOutgoingSessionToken(this.currentSessionToken);
- SecurityTraceRecordHelper.TraceSessionKeyRenewed(this.currentSessionToken, this.previousSessionToken, this.RemoteAddress);
- }
- }
- void RenewKey(TimeSpan timeout)
- {
- if (!this.settings.CanRenewSession)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SessionKeyExpiredException(SR.GetString(SR.SessionKeyRenewalNotSupported)));
- }
- bool startKeyRenewal;
- lock (ThisLock)
- {
- if (!this.isKeyRenewalOngoing)
- {
- this.isKeyRenewalOngoing = true;
- this.keyRenewalCompletedEvent.Reset();
- startKeyRenewal = true;
- }
- else
- {
- startKeyRenewal = false;
- }
- }
- if (startKeyRenewal == true)
- {
- try
- {
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateBoundedActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityRenew), ActivityType.SecuritySetup);
- }
- SecurityToken renewedToken = this.sessionTokenProvider.RenewToken(timeout, this.currentSessionToken);
- UpdateSessionTokens(renewedToken);
- }
- }
- finally
- {
- lock (ThisLock)
- {
- this.isKeyRenewalOngoing = false;
- this.keyRenewalCompletedEvent.Set();
- }
- }
- }
- else
- {
- this.keyRenewalCompletedEvent.Wait(timeout);
- lock (ThisLock)
- {
- if (IsKeyRenewalNeeded())
- {
- // the key renewal attempt failed. Throw an exception to the user
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SessionKeyExpiredException(SR.GetString(SR.UnableToRenewSessionKey)));
- }
- }
- }
- }
- bool CheckIfKeyRenewalNeeded()
- {
- bool doKeyRenewal = false;
- lock (ThisLock)
- {
- doKeyRenewal = IsKeyRenewalNeeded();
- DoKeyRolloverIfNeeded();
- }
- return doKeyRenewal;
- }
- protected IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- bool doKeyRenewal = CheckIfKeyRenewalNeeded();
- if (!doKeyRenewal)
- {
- SecurityProtocolCorrelationState correlationState = this.securityProtocol.SecureOutgoingMessage(ref message, timeout, null);
- return new CompletedAsyncResult<Message, SecurityProtocolCorrelationState>(message, correlationState, callback, state);
- }
- else
- {
- return new KeyRenewalAsyncResult(message, this, timeout, callback, state);
- }
- }
- protected Message EndSecureOutgoingMessage(IAsyncResult result, out SecurityProtocolCorrelationState correlationState)
- {
- if (result is CompletedAsyncResult<Message, SecurityProtocolCorrelationState>)
- {
- return CompletedAsyncResult<Message, SecurityProtocolCorrelationState>.End(result, out correlationState);
- }
- else
- {
- TimeSpan remainingTime;
- Message message = KeyRenewalAsyncResult.End(result, out remainingTime);
- correlationState = this.securityProtocol.SecureOutgoingMessage(ref message, remainingTime, null);
- return message;
- }
- }
- protected SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout)
- {
- bool doKeyRenewal = CheckIfKeyRenewalNeeded();
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- if (doKeyRenewal)
- {
- RenewKey(timeoutHelper.RemainingTime());
- }
- return this.securityProtocol.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime(), null);
- }
- protected void VerifyIncomingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
- {
- this.securityProtocol.VerifyIncomingMessage(ref message, timeout, correlationState);
- }
- protected virtual void AbortCore()
- {
- if (this.channelBinder != null)
- {
- this.channelBinder.Abort();
- }
- if (this.sessionTokenProvider != null)
- {
- SecurityUtils.AbortTokenProviderIfRequired(this.sessionTokenProvider);
- }
- }
- protected virtual void CloseCore(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- try
- {
- if (this.channelBinder != null)
- {
- this.channelBinder.Close(timeoutHelper.RemainingTime());
- }
- if (this.sessionTokenProvider != null)
- {
- SecurityUtils.CloseTokenProviderIfRequired(this.sessionTokenProvider, timeoutHelper.RemainingTime());
- }
- this.keyRenewalCompletedEvent.Abort(this);
- this.inputSessionClosedHandle.Abort(this);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.State != CommunicationState.Closed)
- {
- throw;
- }
- }
- }
- protected virtual IAsyncResult BeginCloseCore(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new CloseCoreAsyncResult(this, timeout, callback, state);
- }
- protected virtual void EndCloseCore(IAsyncResult result)
- {
- CloseCoreAsyncResult.End(result);
- }
- protected IAsyncResult BeginReceiveInternal(TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
- {
- return new ReceiveAsyncResult(this, timeout, correlationState, callback, state);
- }
- protected Message EndReceiveInternal(IAsyncResult result)
- {
- return ReceiveAsyncResult.End(result);
- }
- protected Message ReceiveInternal(TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- while (!this.isInputClosed)
- {
- RequestContext requestContext;
- if (this.ChannelBinder.TryReceive(timeoutHelper.RemainingTime(), out requestContext))
- {
- if (requestContext == null)
- {
- return null;
- }
- Message message = ProcessRequestContext(requestContext, timeoutHelper.RemainingTime(), correlationState);
- if (message != null)
- {
- return message;
- }
- }
- if (timeoutHelper.RemainingTime() == TimeSpan.Zero)
- {
- // we timed out
- break;
- }
- }
- return null;
- }
- protected bool CloseSession(TimeSpan timeout, out bool wasAborted)
- {
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateBoundedActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup);
- }
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- wasAborted = false;
- try
- {
- this.CloseOutputSession(timeoutHelper.RemainingTime());
- return this.inputSessionClosedHandle.Wait(timeoutHelper.RemainingTime(), false);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.State != CommunicationState.Closed)
- {
- throw;
- }
- wasAborted = true;
- }
- return false;
- }
- }
- protected IAsyncResult BeginCloseSession(TimeSpan timeout, AsyncCallback callback, object state)
- {
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
- ServiceModelActivity.CreateAsyncActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, SR.GetString(SR.ActivitySecurityClose), ActivityType.SecuritySetup);
- }
- return new CloseSessionAsyncResult(timeout, this, callback, state);
- }
- }
- protected bool EndCloseSession(IAsyncResult result, out bool wasAborted)
- {
- return CloseSessionAsyncResult.End(result, out wasAborted);
- }
- void DetermineCloseMessageToSend(out bool sendClose, out bool sendCloseResponse)
- {
- sendClose = false;
- sendCloseResponse = false;
- lock (ThisLock)
- {
- if (!this.isOutputClosed)
- {
- this.isOutputClosed = true;
- if (this.receivedClose)
- {
- sendCloseResponse = true;
- }
- else
- {
- sendClose = true;
- this.sentClose = true;
- }
- this.outputSessionCloseHandle.Reset();
- }
- }
- }
- protected virtual SecurityProtocolCorrelationState CloseOutputSession(TimeSpan timeout)
- {
- ThrowIfFaulted();
- if (!this.SendCloseHandshake)
- {
- return null;
- }
- bool sendClose;
- bool sendCloseResponse;
- DetermineCloseMessageToSend(out sendClose, out sendCloseResponse);
- if (sendClose || sendCloseResponse)
- {
- try
- {
- if (sendClose)
- {
- return this.SendCloseMessage(timeout);
- }
- else
- {
- this.SendCloseResponseMessage(timeout);
- return null;
- }
- }
- finally
- {
- this.outputSessionCloseHandle.Set();
- }
- }
- else
- {
- return null;
- }
- }
- protected virtual IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state)
- {
- ThrowIfFaulted();
- if (!this.SendCloseHandshake)
- {
- return new CompletedAsyncResult(callback, state);
- }
- bool sendClose;
- bool sendCloseResponse;
- DetermineCloseMessageToSend(out sendClose, out sendCloseResponse);
- if (sendClose || sendCloseResponse)
- {
- bool setOutputSessionCloseHandle = true;
- try
- {
- IAsyncResult result;
- if (sendClose)
- {
- result = this.BeginSendCloseMessage(timeout, callback, state);
- }
- else
- {
- result = this.BeginSendCloseResponseMessage(timeout, callback, state);
- }
- setOutputSessionCloseHandle = false;
- return result;
- }
- finally
- {
- if (setOutputSessionCloseHandle)
- {
- this.outputSessionCloseHandle.Set();
- }
- }
- }
- else
- {
- return new CompletedAsyncResult(callback, state);
- }
- }
- protected virtual SecurityProtocolCorrelationState EndCloseOutputSession(IAsyncResult result)
- {
- if (result is CompletedAsyncResult)
- {
- CompletedAsyncResult.End(result);
- return null;
- }
- bool sentCloseLocal;
- lock (ThisLock)
- {
- sentCloseLocal = this.sentClose;
- }
- try
- {
- if (sentCloseLocal)
- {
- return this.EndSendCloseMessage(result);
- }
- else
- {
- this.EndSendCloseResponseMessage(result);
- return null;
- }
- }
- finally
- {
- this.outputSessionCloseHandle.Set();
- }
- }
- protected void CheckOutputOpen()
- {
- ThrowIfClosedOrNotOpen();
- lock (ThisLock)
- {
- if (isOutputClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new CommunicationException(SR.GetString(SR.OutputNotExpected)));
- }
- }
- }
- protected override void OnAbort()
- {
- this.AbortCore();
- this.inputSessionClosedHandle.Abort(this);
- this.keyRenewalCompletedEvent.Abort(this);
- this.outputSessionCloseHandle.Abort(this);
- }
- protected override void OnClose(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- if (this.SendCloseHandshake)
- {
- bool wasAborted;
- bool wasSessionClosed = this.CloseSession(timeout, out wasAborted);
- if (wasAborted)
- {
- return;
- }
- if (!wasSessionClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, timeout)));
- }
- // wait for any concurrent output session close to finish
- try
- {
- if (!this.outputSessionCloseHandle.Wait(timeoutHelper.RemainingTime(), false))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, timeoutHelper.OriginalTimeout)));
- }
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.State == CommunicationState.Closed)
- {
- return;
- }
- else
- {
- throw;
- }
- }
- }
- this.CloseCore(timeoutHelper.RemainingTime());
- }
- protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new CloseAsyncResult(this, timeout, callback, state);
- }
- protected override void OnEndClose(IAsyncResult result)
- {
- CloseAsyncResult.End(result);
- }
- class CloseCoreAsyncResult : TraceAsyncResult
- {
- static AsyncCallback closeChannelBinderCallback = Fx.ThunkCallback(new AsyncCallback(ChannelBinderCloseCallback));
- static AsyncCallback closeTokenProviderCallback = Fx.ThunkCallback(new AsyncCallback(CloseTokenProviderCallback));
- TimeoutHelper timeoutHelper;
- ClientSecuritySessionChannel channel;
- public CloseCoreAsyncResult(ClientSecuritySessionChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.channel = channel;
- this.timeoutHelper = new TimeoutHelper(timeout);
- bool completeSelf = false;
- if (channel.channelBinder != null)
- {
- try
- {
- IAsyncResult result = this.channel.channelBinder.BeginClose(timeoutHelper.RemainingTime(), closeChannelBinderCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- this.channel.channelBinder.EndClose(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- completeSelf = true;
- }
- }
- if (!completeSelf)
- {
- completeSelf = this.OnChannelBinderClosed();
- }
- if (completeSelf)
- {
- Complete(true);
- }
- }
- static void ChannelBinderCloseCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseCoreAsyncResult self = (CloseCoreAsyncResult)(result.AsyncState);
- Exception completionException = null;
- bool completeSelf = false;
- try
- {
- try
- {
- self.channel.channelBinder.EndClose(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (self.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- completeSelf = true;
- }
- if (!completeSelf)
- {
- completeSelf = self.OnChannelBinderClosed();
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- bool OnChannelBinderClosed()
- {
- if (channel.sessionTokenProvider != null)
- {
- try
- {
- IAsyncResult result = SecurityUtils.BeginCloseTokenProviderIfRequired(this.channel.sessionTokenProvider, timeoutHelper.RemainingTime(), closeTokenProviderCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- SecurityUtils.EndCloseTokenProviderIfRequired(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (channel.State != CommunicationState.Closed)
- {
- throw;
- }
- return true;
- }
- }
- return this.OnTokenProviderClosed();
- }
- static void CloseTokenProviderCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseCoreAsyncResult self = (CloseCoreAsyncResult)(result.AsyncState);
- Exception completionException = null;
- bool completeSelf = false;
- try
- {
- try
- {
- SecurityUtils.EndCloseTokenProviderIfRequired(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (self.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- completeSelf = true;
- }
- if (!completeSelf)
- {
- completeSelf = self.OnTokenProviderClosed();
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- bool OnTokenProviderClosed()
- {
- this.channel.keyRenewalCompletedEvent.Abort(this.channel);
- this.channel.inputSessionClosedHandle.Abort(this.channel);
- return true;
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<CloseCoreAsyncResult>(result);
- }
- }
- class ReceiveAsyncResult : TraceAsyncResult
- {
- static AsyncCallback onReceive = Fx.ThunkCallback(new AsyncCallback(OnReceive));
- ClientSecuritySessionChannel channel;
- Message message;
- SecurityProtocolCorrelationState correlationState;
- TimeoutHelper timeoutHelper;
- public ReceiveAsyncResult(ClientSecuritySessionChannel channel, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.channel = channel;
- this.correlationState = correlationState;
- this.timeoutHelper = new TimeoutHelper(timeout);
- IAsyncResult result = channel.ChannelBinder.BeginTryReceive(timeoutHelper.RemainingTime(), onReceive, this);
- if (!result.CompletedSynchronously)
- return;
- bool completedSynchronously = CompleteReceive(result);
- if (completedSynchronously)
- {
- Complete(true);
- }
- }
- bool CompleteReceive(IAsyncResult result)
- {
- while (!channel.isInputClosed)
- {
- RequestContext requestContext;
- if (channel.ChannelBinder.EndTryReceive(result, out requestContext))
- {
- if (requestContext == null)
- break;
- message = channel.ProcessRequestContext(requestContext, timeoutHelper.RemainingTime(), this.correlationState);
- if (message != null || channel.isInputClosed)
- break;
- }
- TimeSpan timeout = timeoutHelper.RemainingTime();
- if (timeout == TimeSpan.Zero)
- {
- // we timed out
- break;
- }
- result = channel.ChannelBinder.BeginTryReceive(timeoutHelper.RemainingTime(), onReceive, this);
- if (!result.CompletedSynchronously)
- return false;
- }
- return true;
- }
- public static Message End(IAsyncResult result)
- {
- ReceiveAsyncResult receiveResult = AsyncResult.End<ReceiveAsyncResult>(result);
- return receiveResult.message;
- }
- static void OnReceive(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- return;
- ReceiveAsyncResult self = (ReceiveAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- completeSelf = self.CompleteReceive(result);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- }
- class OpenAsyncResult : TraceAsyncResult
- {
- static readonly AsyncCallback getTokenCallback = Fx.ThunkCallback(new AsyncCallback(GetTokenCallback));
- static readonly AsyncCallback openTokenProviderCallback = Fx.ThunkCallback(new AsyncCallback(OpenTokenProviderCallback));
- ClientSecuritySessionChannel sessionChannel;
- TimeoutHelper timeoutHelper;
- public OpenAsyncResult(ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.sessionChannel = sessionChannel;
- this.sessionChannel.SetupSessionTokenProvider();
- IAsyncResult result = SecurityUtils.BeginOpenTokenProviderIfRequired(this.sessionChannel.sessionTokenProvider, timeoutHelper.RemainingTime(), openTokenProviderCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- SecurityUtils.EndOpenTokenProviderIfRequired(result);
- bool completeSelf = this.OnTokenProviderOpened();
- if (completeSelf)
- {
- Complete(true);
- }
- }
- static void OpenTokenProviderCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- OpenAsyncResult thisAsyncResult = (OpenAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- SecurityUtils.EndOpenTokenProviderIfRequired(result);
- completeSelf = thisAsyncResult.OnTokenProviderOpened();
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisAsyncResult.Complete(false, completionException);
- }
- }
- bool OnTokenProviderOpened()
- {
- IAsyncResult result = this.sessionChannel.sessionTokenProvider.BeginGetToken(timeoutHelper.RemainingTime(), getTokenCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- SecurityToken sessionToken = this.sessionChannel.sessionTokenProvider.EndGetToken(result);
- return this.OnTokenObtained(sessionToken);
- }
- bool OnTokenObtained(SecurityToken sessionToken)
- {
- // Token was issued, do send cancel on close;
- this.sessionChannel.sendCloseHandshake = true;
- this.sessionChannel.OpenCore(sessionToken, timeoutHelper.RemainingTime());
- return true;
- }
- static void GetTokenCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- OpenAsyncResult thisAsyncResult = (OpenAsyncResult)result.AsyncState;
- try
- {
- using (ServiceModelActivity.BoundOperation(thisAsyncResult.CallbackActivity))
- {
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- SecurityToken sessionToken = thisAsyncResult.sessionChannel.sessionTokenProvider.EndGetToken(result);
- completeSelf = thisAsyncResult.OnTokenObtained(sessionToken);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisAsyncResult.Complete(false, completionException);
- }
- }
- }
- finally
- {
- if (thisAsyncResult.CallbackActivity != null)
- {
- thisAsyncResult.CallbackActivity.Dispose();
- }
- }
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<OpenAsyncResult>(result);
- ServiceModelActivity.Stop(((OpenAsyncResult)result).CallbackActivity);
- }
- }
- class CloseSessionAsyncResult : TraceAsyncResult
- {
- static readonly AsyncCallback closeOutputSessionCallback = Fx.ThunkCallback(new AsyncCallback(CloseOutputSessionCallback));
- static readonly AsyncCallback shutdownWaitCallback = Fx.ThunkCallback(new AsyncCallback(ShutdownWaitCallback));
- ClientSecuritySessionChannel sessionChannel;
- bool closeCompleted;
- bool wasAborted;
- TimeoutHelper timeoutHelper;
- public CloseSessionAsyncResult(TimeSpan timeout, ClientSecuritySessionChannel sessionChannel, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.sessionChannel = sessionChannel;
- bool completeSelf = false;
- try
- {
- IAsyncResult result = this.sessionChannel.BeginCloseOutputSession(timeoutHelper.RemainingTime(), closeOutputSessionCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- this.sessionChannel.EndCloseOutputSession(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.sessionChannel.State != CommunicationState.Closed)
- {
- throw;
- }
- completeSelf = true;
- wasAborted = true;
- }
- if (!wasAborted)
- {
- completeSelf = this.OnOutputSessionClosed();
- }
- if (completeSelf)
- {
- Complete(true);
- }
- }
- static void CloseOutputSessionCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseSessionAsyncResult thisResult = (CloseSessionAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- try
- {
- thisResult.sessionChannel.EndCloseOutputSession(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (thisResult.sessionChannel.State != CommunicationState.Closed)
- {
- throw;
- }
- thisResult.wasAborted = true;
- completeSelf = true;
- }
- if (!thisResult.wasAborted)
- {
- completeSelf = thisResult.OnOutputSessionClosed();
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisResult.Complete(false, completionException);
- }
- }
- bool OnOutputSessionClosed()
- {
- try
- {
- IAsyncResult result = this.sessionChannel.inputSessionClosedHandle.BeginWait(this.timeoutHelper.RemainingTime(), true, shutdownWaitCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- this.sessionChannel.inputSessionClosedHandle.EndWait(result);
- this.closeCompleted = true;
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.sessionChannel.State != CommunicationState.Closed)
- {
- throw;
- }
- // if the channel was aborted by a parallel thread, allow the Close to
- // complete cleanly
- this.wasAborted = true;
- }
- catch (TimeoutException)
- {
- this.closeCompleted = false;
- }
- return true;
- }
- static void ShutdownWaitCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseSessionAsyncResult thisResult = (CloseSessionAsyncResult)result.AsyncState;
- Exception completionException = null;
- try
- {
- thisResult.sessionChannel.inputSessionClosedHandle.EndWait(result);
- thisResult.closeCompleted = true;
- }
- catch (CommunicationObjectAbortedException)
- {
- if (thisResult.sessionChannel.State != CommunicationState.Closed)
- {
- throw;
- }
- thisResult.wasAborted = true;
- }
- catch (TimeoutException)
- {
- thisResult.closeCompleted = false;
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- thisResult.Complete(false, completionException);
- }
- public static bool End(IAsyncResult result, out bool wasAborted)
- {
- CloseSessionAsyncResult thisResult = AsyncResult.End<CloseSessionAsyncResult>(result);
- wasAborted = thisResult.wasAborted;
- ServiceModelActivity.Stop(thisResult.CallbackActivity);
- return thisResult.closeCompleted;
- }
- }
- class CloseAsyncResult : TraceAsyncResult
- {
- static readonly AsyncCallback closeSessionCallback = Fx.ThunkCallback(new AsyncCallback(CloseSessionCallback));
- static readonly AsyncCallback outputSessionClosedCallback = Fx.ThunkCallback(new AsyncCallback(OutputSessionClosedCallback));
- static readonly AsyncCallback closeCoreCallback = Fx.ThunkCallback(new AsyncCallback(CloseCoreCallback));
- ClientSecuritySessionChannel sessionChannel;
- TimeoutHelper timeoutHelper;
- public CloseAsyncResult(ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- sessionChannel.ThrowIfFaulted();
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.sessionChannel = sessionChannel;
- if (!sessionChannel.SendCloseHandshake)
- {
- if (this.CloseCore())
- {
- Complete(true);
- }
- return;
- }
- bool wasClosed;
- bool wasAborted = false;
- IAsyncResult result = this.sessionChannel.BeginCloseSession(this.timeoutHelper.RemainingTime(), closeSessionCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- wasClosed = this.sessionChannel.EndCloseSession(result, out wasAborted);
- if (wasAborted)
- {
- Complete(true);
- return;
- }
- if (!wasClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, timeout)));
- }
- bool completeSelf = this.OnWaitForOutputSessionClose(out wasAborted);
- if (wasAborted || completeSelf)
- {
- Complete(true);
- }
- }
- static void CloseSessionCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseAsyncResult thisResult = (CloseAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- bool wasAborted;
- bool wasClosed = thisResult.sessionChannel.EndCloseSession(result, out wasAborted);
- if (wasAborted)
- {
- completeSelf = true;
- }
- else
- {
- if (!wasClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityCloseTimeout, thisResult.timeoutHelper.OriginalTimeout)));
- }
- completeSelf = thisResult.OnWaitForOutputSessionClose(out wasAborted);
- if (wasAborted)
- {
- completeSelf = true;
- }
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisResult.Complete(false, completionException);
- }
- }
- bool OnWaitForOutputSessionClose(out bool wasAborted)
- {
- wasAborted = false;
- bool wasOutputSessionClosed = false;
- // wait for pending output sessions to finish
- try
- {
- IAsyncResult result = this.sessionChannel.outputSessionCloseHandle.BeginWait(timeoutHelper.RemainingTime(), true, outputSessionClosedCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- this.sessionChannel.outputSessionCloseHandle.EndWait(result);
- wasOutputSessionClosed = true;
- }
- catch (TimeoutException)
- {
- wasOutputSessionClosed = false;
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.sessionChannel.State == CommunicationState.Closed)
- {
- wasAborted = true;
- }
- else
- {
- throw;
- }
- }
- if (wasAborted)
- {
- return true;
- }
- if (!wasOutputSessionClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, timeoutHelper.OriginalTimeout)));
- }
- else
- {
- return this.CloseCore();
- }
- }
- static void OutputSessionClosedCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseAsyncResult self = (CloseAsyncResult)(result.AsyncState);
- Exception completionException = null;
- bool completeSelf = false;
- try
- {
- bool wasOutputSessionClosed = false;
- bool wasAborted = false;
- try
- {
- self.sessionChannel.outputSessionCloseHandle.EndWait(result);
- wasOutputSessionClosed = true;
- }
- catch (TimeoutException)
- {
- wasOutputSessionClosed = false;
- }
- catch (CommunicationObjectFaultedException)
- {
- if (self.sessionChannel.State == CommunicationState.Closed)
- {
- wasAborted = true;
- }
- else
- {
- throw;
- }
- }
- if (!wasAborted)
- {
- if (!wasOutputSessionClosed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new TimeoutException(SR.GetString(SR.ClientSecurityOutputSessionCloseTimeout, self.timeoutHelper.OriginalTimeout)));
- }
- completeSelf = self.CloseCore();
- }
- else
- {
- completeSelf = true;
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- completeSelf = true;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- bool CloseCore()
- {
- IAsyncResult result = this.sessionChannel.BeginCloseCore(timeoutHelper.RemainingTime(), closeCoreCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- this.sessionChannel.EndCloseCore(result);
- return true;
- }
- static void CloseCoreCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseAsyncResult self = (CloseAsyncResult)(result.AsyncState);
- Exception completionException = null;
- try
- {
- self.sessionChannel.EndCloseCore(result);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- self.Complete(false, completionException);
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<CloseAsyncResult>(result);
- }
- }
- class KeyRenewalAsyncResult : TraceAsyncResult
- {
- static readonly Action<object> renewKeyCallback = new Action<object>(RenewKeyCallback);
- Message message;
- ClientSecuritySessionChannel sessionChannel;
- TimeoutHelper timeoutHelper;
- public KeyRenewalAsyncResult(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- timeoutHelper = new TimeoutHelper(timeout);
- this.message = message;
- this.sessionChannel = sessionChannel;
- // its ok to start up a separate thread for this since this is a very rare event.
- ActionItem.Schedule(renewKeyCallback, this);
- }
- static void RenewKeyCallback(object state)
- {
- KeyRenewalAsyncResult thisResult = (KeyRenewalAsyncResult)state;
- Exception completionException = null;
- try
- {
- using (thisResult.CallbackActivity == null ? null : ServiceModelActivity.BoundOperation(thisResult.CallbackActivity))
- {
- thisResult.sessionChannel.RenewKey(thisResult.timeoutHelper.RemainingTime());
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- thisResult.Complete(false, completionException);
- }
- public static Message End(IAsyncResult result, out TimeSpan remainingTime)
- {
- KeyRenewalAsyncResult thisResult = AsyncResult.End<KeyRenewalAsyncResult>(result);
- remainingTime = thisResult.timeoutHelper.RemainingTime();
- return thisResult.message;
- }
- }
- internal abstract class SecureSendAsyncResultBase : TraceAsyncResult
- {
- static readonly AsyncCallback secureOutgoingMessageCallback = Fx.ThunkCallback(new AsyncCallback(SecureOutgoingMessageCallback));
- Message message;
- SecurityProtocolCorrelationState correlationState;
- ClientSecuritySessionChannel sessionChannel;
- bool didSecureOutgoingMessageCompleteSynchronously = false;
- TimeoutHelper timeoutHelper;
- protected SecureSendAsyncResultBase(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.message = message;
- this.sessionChannel = sessionChannel;
- this.timeoutHelper = new TimeoutHelper(timeout);
- IAsyncResult result = this.sessionChannel.BeginSecureOutgoingMessage(message, timeoutHelper.RemainingTime(), secureOutgoingMessageCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- this.message = this.sessionChannel.EndSecureOutgoingMessage(result, out this.correlationState);
- this.didSecureOutgoingMessageCompleteSynchronously = true;
- }
- protected bool DidSecureOutgoingMessageCompleteSynchronously
- {
- get
- {
- return this.didSecureOutgoingMessageCompleteSynchronously;
- }
- }
- protected TimeoutHelper TimeoutHelper
- {
- get
- {
- return this.timeoutHelper;
- }
- }
- protected IClientReliableChannelBinder ChannelBinder
- {
- get
- {
- return this.sessionChannel.ChannelBinder;
- }
- }
- protected Message Message
- {
- get
- {
- return this.message;
- }
- }
- protected SecurityProtocolCorrelationState SecurityCorrelationState
- {
- get
- {
- return this.correlationState;
- }
- }
- protected abstract bool OnMessageSecured();
- static void SecureOutgoingMessageCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- SecureSendAsyncResultBase thisResult = (SecureSendAsyncResultBase)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- thisResult.message = thisResult.sessionChannel.EndSecureOutgoingMessage(result, out thisResult.correlationState);
- completeSelf = thisResult.OnMessageSecured();
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisResult.Complete(false, completionException);
- }
- }
- }
- internal sealed class SecureSendAsyncResult : SecureSendAsyncResultBase
- {
- static readonly AsyncCallback sendCallback = Fx.ThunkCallback(new AsyncCallback(SendCallback));
- bool autoCloseMessage;
- public SecureSendAsyncResult(Message message, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state, bool autoCloseMessage)
- : base(message, sessionChannel, timeout, callback, state)
- {
- this.autoCloseMessage = autoCloseMessage;
- if (!this.DidSecureOutgoingMessageCompleteSynchronously)
- {
- return;
- }
- bool completeSelf = this.OnMessageSecured();
- if (completeSelf)
- {
- Complete(true);
- }
- }
- protected override bool OnMessageSecured()
- {
- bool closeMessage = true;
- try
- {
- IAsyncResult result = this.ChannelBinder.BeginSend(this.Message, this.TimeoutHelper.RemainingTime(), sendCallback, this);
- if (!result.CompletedSynchronously)
- {
- closeMessage = false;
- return false;
- }
- this.ChannelBinder.EndSend(result);
- return true;
- }
- finally
- {
- if (closeMessage && this.autoCloseMessage && this.Message != null)
- {
- this.Message.Close();
- }
- }
- }
- static void SendCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- SecureSendAsyncResult thisResult = (SecureSendAsyncResult)result.AsyncState;
- Exception completionException = null;
- try
- {
- thisResult.ChannelBinder.EndSend(result);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- finally
- {
- if (thisResult.autoCloseMessage && thisResult.Message != null)
- {
- thisResult.Message.Close();
- }
- if (thisResult.CallbackActivity != null && DiagnosticUtility.ShouldUseActivity)
- {
- thisResult.CallbackActivity.Stop();
- }
- }
- thisResult.Complete(false, completionException);
- }
- public static SecurityProtocolCorrelationState End(IAsyncResult result)
- {
- SecureSendAsyncResult thisResult = AsyncResult.End<SecureSendAsyncResult>(result);
- return thisResult.SecurityCorrelationState;
- }
- }
- protected class SoapSecurityOutputSession : ISecureConversationSession, IOutputSession
- {
- ClientSecuritySessionChannel channel;
- EndpointIdentity remoteIdentity;
- UniqueId sessionId;
- SecurityKeyIdentifierClause sessionTokenIdentifier;
- SecurityStandardsManager standardsManager;
- public SoapSecurityOutputSession(ClientSecuritySessionChannel channel)
- {
- this.channel = channel;
- }
- internal void Initialize(SecurityToken sessionToken, SecuritySessionClientSettings<TChannel> settings)
- {
- if (sessionToken == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sessionToken");
- }
- if (settings == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("settings");
- }
- Claim identityClaim = SecurityUtils.GetPrimaryIdentityClaim(((GenericXmlSecurityToken)sessionToken).AuthorizationPolicies);
- if (identityClaim != null)
- {
- this.remoteIdentity = EndpointIdentity.CreateIdentity(identityClaim);
- }
- this.standardsManager = settings.SessionProtocolFactory.StandardsManager;
- this.sessionId = GetSessionId(sessionToken, this.standardsManager);
- this.sessionTokenIdentifier = settings.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(sessionToken,
- SecurityTokenReferenceStyle.External);
- }
- UniqueId GetSessionId(SecurityToken sessionToken, SecurityStandardsManager standardsManager)
- {
- GenericXmlSecurityToken gxt = sessionToken as GenericXmlSecurityToken;
- if (gxt == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SessionTokenIsNotGenericXmlToken, sessionToken, typeof(GenericXmlSecurityToken))));
- }
- return standardsManager.SecureConversationDriver.GetSecurityContextTokenId(XmlDictionaryReader.CreateDictionaryReader(new XmlNodeReader(gxt.TokenXml)));
- }
- public string Id
- {
- get
- {
- if (this.sessionId == null)
- {
- // PreSharp Bug: Property get methods should not throw exceptions.
- #pragma warning suppress 56503
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelMustBeOpenedToGetSessionId)));
- }
- return this.sessionId.ToString();
- }
- }
- public EndpointIdentity RemoteIdentity
- {
- get
- {
- return this.remoteIdentity;
- }
- }
- public void WriteSessionTokenIdentifier(XmlDictionaryWriter writer)
- {
- this.channel.ThrowIfDisposedOrNotOpen();
- this.standardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, this.sessionTokenIdentifier);
- }
- public bool TryReadSessionTokenIdentifier(XmlReader reader)
- {
- this.channel.ThrowIfDisposedOrNotOpen();
- if (!this.standardsManager.SecurityTokenSerializer.CanReadKeyIdentifierClause(reader))
- {
- return false;
- }
- SecurityContextKeyIdentifierClause incomingTokenIdentifier =
- this.standardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(reader) as SecurityContextKeyIdentifierClause;
- return incomingTokenIdentifier != null && incomingTokenIdentifier.Matches(sessionId, null);
- }
- }
- }
- abstract class ClientSecuritySimplexSessionChannel : ClientSecuritySessionChannel
- {
- SoapSecurityOutputSession outputSession;
- protected ClientSecuritySimplexSessionChannel(SecuritySessionClientSettings<TChannel> settings, EndpointAddress to, Uri via)
- : base(settings, to, via)
- {
- this.outputSession = new SoapSecurityOutputSession(this);
- }
- public IOutputSession Session
- {
- get
- {
- return this.outputSession;
- }
- }
- protected override bool ExpectClose
- {
- get { return false; }
- }
- protected override string SessionId
- {
- get { return this.Session.Id; }
- }
- protected override void InitializeSession(SecurityToken sessionToken)
- {
- this.outputSession.Initialize(sessionToken, this.Settings);
- }
- }
- sealed class SecurityRequestSessionChannel : ClientSecuritySimplexSessionChannel, IRequestSessionChannel
- {
- public SecurityRequestSessionChannel(SecuritySessionClientSettings<TChannel> settings, EndpointAddress to, Uri via)
- : base(settings, to, via)
- {
- }
- protected override bool CanDoSecurityCorrelation
- {
- get
- {
- return true;
- }
- }
- protected override SecurityProtocolCorrelationState CloseOutputSession(TimeSpan timeout)
- {
- ThrowIfFaulted();
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- SecurityProtocolCorrelationState correlationState = base.CloseOutputSession(timeoutHelper.RemainingTime());
- Message message = ReceiveInternal(timeoutHelper.RemainingTime(), correlationState);
- if (message != null)
- {
- using (message)
- {
- ProtocolException error = ProtocolException.ReceiveShutdownReturnedNonNull(message);
- throw TraceUtility.ThrowHelperWarning(error, message);
- }
- }
- return null;
- }
- protected override IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state)
- {
- ThrowIfFaulted();
- return new CloseOutputSessionAsyncResult(this, timeout, callback, state);
- }
- protected override SecurityProtocolCorrelationState EndCloseOutputSession(IAsyncResult result)
- {
- CloseOutputSessionAsyncResult.End(result);
- return null;
- }
- IAsyncResult BeginBaseCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return base.BeginCloseOutputSession(timeout, callback, state);
- }
- SecurityProtocolCorrelationState EndBaseCloseOutputSession(IAsyncResult result)
- {
- return base.EndCloseOutputSession(result);
- }
- public Message Request(Message message)
- {
- return this.Request(message, this.DefaultSendTimeout);
- }
- Message ProcessReply(Message reply, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
- {
- if (reply == null)
- {
- return null;
- }
- Message unverifiedReply = reply;
- Message processedReply = null;
- MessageFault protocolFault = null;
- Exception faultException = null;
- try
- {
- processedReply = this.ProcessIncomingMessage(reply, timeout, correlationState, out protocolFault);
- }
- catch (MessageSecurityException)
- {
- if (unverifiedReply.IsFault)
- {
- MessageFault fault = MessageFault.CreateFault(unverifiedReply, TransportDefaults.MaxSecurityFaultSize);
- if (SecurityUtils.IsSecurityFault(fault, this.Settings.standardsManager))
- {
- faultException = SecurityUtils.CreateSecurityFaultException(fault);
- }
- }
- if (faultException == null)
- {
- throw;
- }
- }
- if (faultException != null)
- {
- Fault(faultException);
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(faultException);
- }
- if (processedReply == null && protocolFault != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SecuritySessionFaultReplyWasSent), new FaultException(protocolFault)));
- }
- return processedReply;
- }
- public Message Request(Message message, TimeSpan timeout)
- {
- ThrowIfFaulted();
- CheckOutputOpen();
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- SecurityProtocolCorrelationState correlationState = this.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime());
- Message reply = this.ChannelBinder.Request(message, timeoutHelper.RemainingTime());
- return ProcessReply(reply, timeoutHelper.RemainingTime(), correlationState);
- }
- public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
- {
- return this.BeginRequest(message, this.DefaultSendTimeout, callback, state);
- }
- public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- ThrowIfFaulted();
- CheckOutputOpen();
- return new SecureRequestAsyncResult(message, this, timeout, callback, state);
- }
- public Message EndRequest(IAsyncResult result)
- {
- SecurityProtocolCorrelationState requestCorrelationState;
- TimeSpan remainingTime;
- Message reply = SecureRequestAsyncResult.EndAsReply(result, out requestCorrelationState, out remainingTime);
- return ProcessReply(reply, remainingTime, requestCorrelationState);
- }
- sealed class SecureRequestAsyncResult : SecureSendAsyncResultBase
- {
- static readonly AsyncCallback requestCallback = Fx.ThunkCallback(new AsyncCallback(RequestCallback));
- Message reply;
- public SecureRequestAsyncResult(Message request, ClientSecuritySessionChannel sessionChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(request, sessionChannel, timeout, callback, state)
- {
- if (!this.DidSecureOutgoingMessageCompleteSynchronously)
- {
- return;
- }
- bool completeSelf = OnMessageSecured();
- if (completeSelf)
- {
- Complete(true);
- }
- }
- protected override bool OnMessageSecured()
- {
- IAsyncResult result = this.ChannelBinder.BeginRequest(this.Message, this.TimeoutHelper.RemainingTime(), requestCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- this.reply = this.ChannelBinder.EndRequest(result);
- return true;
- }
- static void RequestCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- SecureRequestAsyncResult thisAsyncResult = (SecureRequestAsyncResult)result.AsyncState;
- Exception completionException = null;
- try
- {
- thisAsyncResult.reply = thisAsyncResult.ChannelBinder.EndRequest(result);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- thisAsyncResult.Complete(false, completionException);
- }
- public static Message EndAsReply(IAsyncResult result, out SecurityProtocolCorrelationState correlationState, out TimeSpan remainingTime)
- {
- SecureRequestAsyncResult thisResult = AsyncResult.End<SecureRequestAsyncResult>(result);
- correlationState = thisResult.SecurityCorrelationState;
- remainingTime = thisResult.TimeoutHelper.RemainingTime();
- return thisResult.reply;
- }
- }
- class CloseOutputSessionAsyncResult : TraceAsyncResult
- {
- static readonly AsyncCallback baseCloseOutputSessionCallback = Fx.ThunkCallback(new AsyncCallback(BaseCloseOutputSessionCallback));
- static readonly AsyncCallback receiveInternalCallback = Fx.ThunkCallback(new AsyncCallback(ReceiveInternalCallback));
- SecurityRequestSessionChannel requestChannel;
- SecurityProtocolCorrelationState correlationState;
- TimeoutHelper timeoutHelper;
- public CloseOutputSessionAsyncResult(SecurityRequestSessionChannel requestChannel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.requestChannel = requestChannel;
- IAsyncResult result = this.requestChannel.BeginBaseCloseOutputSession(timeoutHelper.RemainingTime(), baseCloseOutputSessionCallback, this);
- if (!result.CompletedSynchronously)
- {
- return;
- }
- this.correlationState = this.requestChannel.EndBaseCloseOutputSession(result);
- bool completeSelf = this.OnBaseOutputSessionClosed();
- if (completeSelf)
- {
- Complete(true);
- }
- }
- static void BaseCloseOutputSessionCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseOutputSessionAsyncResult thisAsyncResult = (CloseOutputSessionAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- thisAsyncResult.correlationState = thisAsyncResult.requestChannel.EndBaseCloseOutputSession(result);
- completeSelf = thisAsyncResult.OnBaseOutputSessionClosed();
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisAsyncResult.Complete(false, completionException);
- }
- }
- bool OnBaseOutputSessionClosed()
- {
- IAsyncResult result = this.requestChannel.BeginReceiveInternal(this.timeoutHelper.RemainingTime(), this.correlationState, receiveInternalCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- Message message = this.requestChannel.EndReceiveInternal(result);
- return this.OnMessageReceived(message);
- }
- static void ReceiveInternalCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- CloseOutputSessionAsyncResult thisAsyncResult = (CloseOutputSessionAsyncResult)result.AsyncState;
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- Message message = thisAsyncResult.requestChannel.EndReceiveInternal(result);
- completeSelf = thisAsyncResult.OnMessageReceived(message);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- thisAsyncResult.Complete(false, completionException);
- }
- }
- bool OnMessageReceived(Message message)
- {
- if (message != null)
- {
- using (message)
- {
- ProtocolException error = ProtocolException.ReceiveShutdownReturnedNonNull(message);
- throw TraceUtility.ThrowHelperWarning(error, message);
- }
- }
- return true;
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<CloseOutputSessionAsyncResult>(result);
- }
- }
- }
- class ClientSecurityDuplexSessionChannel : ClientSecuritySessionChannel, IDuplexSessionChannel
- {
- static AsyncCallback onReceive = Fx.ThunkCallback(new AsyncCallback(OnReceive));
- SoapSecurityClientDuplexSession session;
- InputQueue<Message> queue;
- Action startReceiving;
- Action<object> completeLater;
- public ClientSecurityDuplexSessionChannel(SecuritySessionClientSettings<TChannel> settings, EndpointAddress to, Uri via)
- : base(settings, to, via)
- {
- this.session = new SoapSecurityClientDuplexSession(this);
- this.queue = TraceUtility.CreateInputQueue<Message>();
- this.startReceiving = new Action(StartReceiving);
- this.completeLater = new Action<object>(CompleteLater);
- }
- public EndpointAddress LocalAddress
- {
- get
- {
- return base.InternalLocalAddress;
- }
- }
- public IDuplexSession Session
- {
- get
- {
- return this.session;
- }
- }
- protected override bool ExpectClose
- {
- get { return true; }
- }
- protected override string SessionId
- {
- get { return this.session.Id; }
- }
- public Message Receive()
- {
- return this.Receive(this.DefaultReceiveTimeout);
- }
- public Message Receive(TimeSpan timeout)
- {
- return InputChannel.HelpReceive(this, timeout);
- }
- public IAsyncResult BeginReceive(AsyncCallback callback, object state)
- {
- return this.BeginReceive(this.DefaultReceiveTimeout, callback, state);
- }
- public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return InputChannel.HelpBeginReceive(this, timeout, callback, state);
- }
- public Message EndReceive(IAsyncResult result)
- {
- return InputChannel.HelpEndReceive(result);
- }
- public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
- {
- ThrowIfFaulted();
- return queue.BeginDequeue(timeout, callback, state);
- }
- public bool EndTryReceive(IAsyncResult result, out Message message)
- {
- bool wasDequeued = queue.EndDequeue(result, out message);
- if (message == null)
- {
- // the channel could have faulted, shutting down the input queue
- ThrowIfFaulted();
- }
- return wasDequeued;
- }
- protected override void OnOpened()
- {
- base.OnOpened();
- StartReceiving();
- }
- public bool TryReceive(TimeSpan timeout, out Message message)
- {
- ThrowIfFaulted();
- bool wasDequeued = queue.Dequeue(timeout, out message);
- if (message == null)
- {
- // the channel could have faulted, shutting down the input queue
- ThrowIfFaulted();
- }
- return wasDequeued;
- }
- public void Send(Message message)
- {
- this.Send(message, this.DefaultSendTimeout);
- }
- public void Send(Message message, TimeSpan timeout)
- {
- ThrowIfFaulted();
- CheckOutputOpen();
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- this.SecureOutgoingMessage(ref message, timeoutHelper.RemainingTime());
- this.ChannelBinder.Send(message, timeoutHelper.RemainingTime());
- }
- public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
- {
- return this.BeginSend(message, this.DefaultSendTimeout, callback, state);
- }
- public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- ThrowIfFaulted();
- CheckOutputOpen();
- return new SecureSendAsyncResult(message, this, timeout, callback, state, false);
- }
- public void EndSend(IAsyncResult result)
- {
- SecureSendAsyncResult.End(result);
- }
- protected override void InitializeSession(SecurityToken sessionToken)
- {
- this.session.Initialize(sessionToken, this.Settings);
- }
- void StartReceiving()
- {
- IAsyncResult result = this.IssueReceive();
- if (result != null && result.CompletedSynchronously)
- {
- ActionItem.Schedule(completeLater, result);
- }
- }
- IAsyncResult IssueReceive()
- {
- while (true)
- {
- // no need to receive anymore if in the closed state
- if (this.State == CommunicationState.Closed || this.State == CommunicationState.Faulted || this.IsInputClosed)
- {
- return null;
- }
- try
- {
- return this.BeginReceiveInternal(TimeSpan.MaxValue, null, onReceive, this);
- }
- catch (CommunicationException e)
- {
- // BeginReceive failed. ignore the exception and start another receive
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- catch (TimeoutException e)
- {
- // BeginReceive failed. ignore the exception and start another receive
- if (TD.ReceiveTimeoutIsEnabled())
- {
- TD.ReceiveTimeout(e.Message);
- }
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- }
- }
- void CompleteLater(object obj)
- {
- CompleteReceive((IAsyncResult)obj);
- }
- static void OnReceive(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- return;
- ((ClientSecurityDuplexSessionChannel)result.AsyncState).CompleteReceive(result);
- }
- void CompleteReceive(IAsyncResult result)
- {
- Message message = null;
- bool issueAnotherReceive = false;
- try
- {
- message = this.EndReceiveInternal(result);
- issueAnotherReceive = true;
- }
- catch (MessageSecurityException)
- {
- // a messagesecurityexception will only be thrown if the channel received a fault
- // from the other side, in which case the channel would have faulted
- issueAnotherReceive = false;
- }
- catch (CommunicationException e)
- {
- issueAnotherReceive = true;
- // EndReceive failed. ignore the exception and start another receive
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- catch (TimeoutException e)
- {
- issueAnotherReceive = true;
- // EndReceive failed. ignore the exception and start another receive
- if (TD.ReceiveTimeoutIsEnabled())
- {
- TD.ReceiveTimeout(e.Message);
- }
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- IAsyncResult nextReceiveResult = null;
- if (issueAnotherReceive)
- {
- nextReceiveResult = this.IssueReceive();
- if (nextReceiveResult != null && nextReceiveResult.CompletedSynchronously)
- {
- ActionItem.Schedule(completeLater, nextReceiveResult);
- }
- }
- if (message != null)
- {
- // since we may be dispatching to user code ---- non-fatal exceptions
- try
- {
- this.queue.EnqueueAndDispatch(message);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e)) throw;
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
- }
- }
- }
- protected override void AbortCore()
- {
- try
- {
- this.queue.Dispose();
- }
- catch (CommunicationException e)
- {
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- catch (TimeoutException e)
- {
- if (TD.CloseTimeoutIsEnabled())
- {
- TD.CloseTimeout(e.Message);
- }
- DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
- }
- base.AbortCore();
- }
- public bool WaitForMessage(TimeSpan timeout)
- {
- return this.queue.WaitForItem(timeout);
- }
- public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return this.queue.BeginWaitForItem(timeout, callback, state);
- }
- public bool EndWaitForMessage(IAsyncResult result)
- {
- return this.queue.EndWaitForItem(result);
- }
- protected override void OnFaulted()
- {
- queue.Shutdown(() => this.GetPendingException());
- base.OnFaulted();
- }
- protected override bool OnCloseResponseReceived()
- {
- if (base.OnCloseResponseReceived())
- {
- this.queue.Shutdown();
- return true;
- }
- else
- {
- return false;
- }
- }
- protected override bool OnCloseReceived()
- {
- if (base.OnCloseReceived())
- {
- this.queue.Shutdown();
- return true;
- }
- else
- {
- return false;
- }
- }
- class SoapSecurityClientDuplexSession : SoapSecurityOutputSession, IDuplexSession
- {
- ClientSecurityDuplexSessionChannel channel;
- bool initialized = false;
- public SoapSecurityClientDuplexSession(ClientSecurityDuplexSessionChannel channel)
- : base(channel)
- {
- this.channel = channel;
- }
- internal new void Initialize(SecurityToken sessionToken, SecuritySessionClientSettings<TChannel> settings)
- {
- base.Initialize(sessionToken, settings);
- this.initialized = true;
- }
- void CheckInitialized()
- {
- if (!this.initialized)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelNotOpen)));
- }
- }
- public void CloseOutputSession()
- {
- this.CloseOutputSession(this.channel.DefaultCloseTimeout);
- }
- public void CloseOutputSession(TimeSpan timeout)
- {
- CheckInitialized();
- this.channel.ThrowIfFaulted();
- this.channel.ThrowIfNotOpened();
- Exception pendingException = null;
- try
- {
- this.channel.CloseOutputSession(timeout);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e)) throw;
- pendingException = e;
- }
- if (pendingException != null)
- {
- this.channel.Fault(pendingException);
- throw pendingException;
- }
- }
- public IAsyncResult BeginCloseOutputSession(AsyncCallback callback, object state)
- {
- return this.BeginCloseOutputSession(this.channel.DefaultCloseTimeout, callback, state);
- }
- public IAsyncResult BeginCloseOutputSession(TimeSpan timeout, AsyncCallback callback, object state)
- {
- CheckInitialized();
- this.channel.ThrowIfFaulted();
- this.channel.ThrowIfNotOpened();
- Exception pendingException = null;
- try
- {
- return this.channel.BeginCloseOutputSession(timeout, callback, state);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- // another thread must have aborted the channel. Allow the close to complete
- // gracefully
- return new CompletedAsyncResult(callback, state);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e)) throw;
- pendingException = e;
- }
- if (pendingException != null)
- {
- this.channel.Fault(pendingException);
- if (pendingException is CommunicationException)
- {
- throw pendingException;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(pendingException);
- }
- }
- // we should never reach here
- Fx.Assert("Unexpected control flow");
- return null;
- }
- public void EndCloseOutputSession(IAsyncResult result)
- {
- if (result is CompletedAsyncResult)
- {
- CompletedAsyncResult.End(result);
- return;
- }
- Exception pendingException = null;
- try
- {
- this.channel.EndCloseOutputSession(result);
- }
- catch (CommunicationObjectAbortedException)
- {
- if (this.channel.State != CommunicationState.Closed)
- {
- throw;
- }
- // another thread must have aborted the channel. Allow the close to complete
- // gracefully
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- if (Fx.IsFatal(e)) throw;
- pendingException = e;
- }
- if (pendingException != null)
- {
- this.channel.Fault(pendingException);
- if (pendingException is CommunicationException)
- {
- throw pendingException;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(pendingException);
- }
- }
- }
- }
- }
- }
- }
|