{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/wcf/pulls/comments/46254997","id":46254997,"diff_hunk":"@@ -0,0 +1,425 @@\n+// Copyright (c) Microsoft. All rights reserved.\n+// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n+\n+using System.Collections.ObjectModel;\n+using System.Diagnostics.Contracts;\n+using System.IdentityModel.Policy;\n+using System.IdentityModel.Selectors;\n+using System.IdentityModel.Tokens;\n+using System.IO;\n+using System.Net;\n+using System.Net.Security;\n+using System.Runtime;\n+using System.Security.Authentication;\n+using System.Security.Principal;\n+using System.ServiceModel;\n+using System.ServiceModel.Description;\n+using System.ServiceModel.Diagnostics.Application;\n+using System.ServiceModel.Security;\n+using System.ServiceModel.Security.Tokens;\n+using System.Threading.Tasks;\n+\n+namespace System.ServiceModel.Channels\n+{\n+    class WindowsStreamSecurityUpgradeProvider : StreamSecurityUpgradeProvider\n+    {\n+        bool _extractGroupsForWindowsAccounts;\n+        EndpointIdentity _identity;\n+        IdentityVerifier _identityVerifier;\n+        ProtectionLevel _protectionLevel;\n+        SecurityTokenManager _securityTokenManager;\n+        NetworkCredential _serverCredential;\n+        string _scheme;\n+        bool _isClient;\n+        Uri _listenUri;\n+\n+        public WindowsStreamSecurityUpgradeProvider(WindowsStreamSecurityBindingElement bindingElement,\n+            BindingContext context, bool isClient)\n+            : base(context.Binding)\n+        {\n+            Contract.Assert(isClient, \".NET Core and .NET Native does not support server side\");\n+\n+            _extractGroupsForWindowsAccounts = TransportDefaults.ExtractGroupsForWindowsAccounts;\n+            _protectionLevel = bindingElement.ProtectionLevel;\n+            _scheme = context.Binding.Scheme;\n+            _isClient = isClient;\n+            _listenUri = TransportSecurityHelpers.GetListenUri(context.ListenUriBaseAddress, context.ListenUriRelativeAddress);\n+\n+            SecurityCredentialsManager credentialProvider = context.BindingParameters.Find<SecurityCredentialsManager>();\n+            if (credentialProvider == null)\n+            {\n+                credentialProvider = ClientCredentials.CreateDefaultCredentials();\n+            }\n+\n+            _securityTokenManager = credentialProvider.CreateSecurityTokenManager();\n+        }\n+\n+        public string Scheme\n+        {\n+            get { return _scheme; }\n+        }\n+\n+        internal bool ExtractGroupsForWindowsAccounts\n+        {\n+            get\n+            {\n+                return _extractGroupsForWindowsAccounts;\n+            }\n+        }\n+\n+        public override EndpointIdentity Identity\n+        {\n+            get\n+            {\n+                // If the server credential is null, then we have not been opened yet and have no identity to expose.\n+                if (_serverCredential != null)\n+                {\n+                    if (_identity == null)\n+                    {\n+                        lock (ThisLock)\n+                        {\n+                            if (_identity == null)\n+                            {\n+                                _identity = SecurityUtils.CreateWindowsIdentity(_serverCredential);\n+                            }\n+                        }\n+                    }\n+                }\n+                return _identity;\n+            }\n+        }\n+\n+        internal IdentityVerifier IdentityVerifier\n+        {\n+            get\n+            {\n+                return _identityVerifier;\n+            }\n+        }\n+\n+        public ProtectionLevel ProtectionLevel\n+        {\n+            get\n+            {\n+                return _protectionLevel;\n+            }\n+        }\n+\n+        NetworkCredential ServerCredential\n+        {\n+            get\n+            {\n+                return _serverCredential;\n+            }\n+        }\n+\n+        public override StreamUpgradeAcceptor CreateUpgradeAcceptor()\n+        {\n+            ThrowIfDisposedOrNotOpen();\n+            return new WindowsStreamSecurityUpgradeAcceptor(this);\n+        }\n+\n+        public override StreamUpgradeInitiator CreateUpgradeInitiator(EndpointAddress remoteAddress, Uri via)\n+        {\n+            ThrowIfDisposedOrNotOpen();\n+            return new WindowsStreamSecurityUpgradeInitiator(this, remoteAddress, via);\n+        }\n+\n+        protected override void OnAbort()\n+        {\n+        }\n+\n+        protected override void OnClose(TimeSpan timeout)\n+        {\n+        }\n+\n+        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)\n+        {\n+            return new CompletedAsyncResult(callback, state);\n+        }\n+\n+        protected override void OnEndClose(IAsyncResult result)\n+        {\n+            CompletedAsyncResult.End(result);\n+        }\n+\n+        protected override void OnOpen(TimeSpan timeout)\n+        {\n+            if (!_isClient)\n+            {\n+                SecurityTokenRequirement sspiTokenRequirement = TransportSecurityHelpers.CreateSspiTokenRequirement(Scheme, _listenUri);\n+                _serverCredential =\n+                    TransportSecurityHelpers.GetSspiCredential(_securityTokenManager, sspiTokenRequirement, timeout,\n+                    out _extractGroupsForWindowsAccounts);\n+            }\n+        }\n+\n+        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)\n+        {\n+            OnOpen(timeout);\n+            return new CompletedAsyncResult(callback, state);\n+        }\n+\n+        protected override void OnEndOpen(IAsyncResult result)\n+        {\n+            CompletedAsyncResult.End(result);\n+        }\n+\n+        protected override void OnOpened()\n+        {\n+            base.OnOpened();\n+\n+            if (_identityVerifier == null)\n+            {\n+                _identityVerifier = IdentityVerifier.CreateDefault();\n+            }\n+\n+            if (_serverCredential == null)\n+            {\n+                _serverCredential = CredentialCache.DefaultNetworkCredentials;\n+            }\n+        }\n+\n+        private class WindowsStreamSecurityUpgradeAcceptor : StreamSecurityUpgradeAcceptorBase\n+        {\n+            private WindowsStreamSecurityUpgradeProvider _parent;\n+            private SecurityMessageProperty _clientSecurity;\n+\n+            public WindowsStreamSecurityUpgradeAcceptor(WindowsStreamSecurityUpgradeProvider parent)\n+                : base(FramingUpgradeString.Negotiate)\n+            {\n+                _parent = parent;\n+                _clientSecurity = new SecurityMessageProperty();\n+            }\n+\n+            protected override Stream OnAcceptUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity)\n+            {\n+                // wrap stream\n+                NegotiateStream negotiateStream = new NegotiateStream(stream);\n+\n+                // authenticate\n+                try\n+                {\n+                    if (TD.WindowsStreamSecurityOnAcceptUpgradeIsEnabled())\n+                    {\n+                        TD.WindowsStreamSecurityOnAcceptUpgrade(EventTraceActivity);\n+                    }\n+\n+                    negotiateStream.AuthenticateAsServer(_parent.ServerCredential, _parent.ProtectionLevel,\n+                        TokenImpersonationLevel.Identification);\n+                }\n+                catch (AuthenticationException exception)\n+                {\n+                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message,\n+                        exception));\n+                }\n+                catch (IOException ioException)\n+                {\n+                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(\n+                        SR.Format(SR.NegotiationFailedIO, ioException.Message), ioException));\n+                }\n+\n+                remoteSecurity = CreateClientSecurity(negotiateStream, _parent.ExtractGroupsForWindowsAccounts);\n+                return negotiateStream;\n+            }\n+\n+            protected override IAsyncResult OnBeginAcceptUpgrade(Stream stream, AsyncCallback callback, object state)\n+            {\n+                throw ExceptionHelper.PlatformNotSupported(); \n+            }\n+\n+            protected override Stream OnEndAcceptUpgrade(IAsyncResult result,\n+                out SecurityMessageProperty remoteSecurity)\n+            {\n+                throw ExceptionHelper.PlatformNotSupported();\n+            }\n+\n+            SecurityMessageProperty CreateClientSecurity(NegotiateStream negotiateStream,\n+                bool extractGroupsForWindowsAccounts)\n+            {\n+                WindowsIdentity remoteIdentity = (WindowsIdentity)negotiateStream.RemoteIdentity;\n+                SecurityUtils.ValidateAnonymityConstraint(remoteIdentity, false);\n+                WindowsSecurityTokenAuthenticator authenticator = new WindowsSecurityTokenAuthenticator(extractGroupsForWindowsAccounts);\n+\n+                // When NegotiateStream returns a WindowsIdentity the AuthenticationType is passed in the constructor to WindowsIdentity\n+                // by it's internal NegoState class.  If this changes, then the call to remoteIdentity.AuthenticationType could fail if the \n+                // current process token doesn't have sufficient priviledges.  It is a first class exception, and caught by the CLR\n+                // null is returned.\n+                SecurityToken token = new WindowsSecurityToken(remoteIdentity, SecurityUniqueId.Create().Value, remoteIdentity.AuthenticationType);\n+                ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = authenticator.ValidateToken(token);\n+                _clientSecurity = new SecurityMessageProperty();\n+                _clientSecurity.TransportToken = new SecurityTokenSpecification(token, authorizationPolicies);\n+                _clientSecurity.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies);\n+                return _clientSecurity;\n+            }\n+\n+            public override SecurityMessageProperty GetRemoteSecurity()\n+            {\n+                if (_clientSecurity.TransportToken != null)\n+                {\n+                    return _clientSecurity;\n+                }\n+                return base.GetRemoteSecurity();\n+            }\n+        }\n+\n+        class WindowsStreamSecurityUpgradeInitiator : StreamSecurityUpgradeInitiatorBase\n+        {\n+            private WindowsStreamSecurityUpgradeProvider _parent;\n+            private IdentityVerifier _identityVerifier;\n+            private NetworkCredential _credential;\n+            private TokenImpersonationLevel _impersonationLevel;\n+            private SspiSecurityTokenProvider _clientTokenProvider;\n+            private bool _allowNtlm;\n+\n+            public WindowsStreamSecurityUpgradeInitiator(\n+                WindowsStreamSecurityUpgradeProvider parent, EndpointAddress remoteAddress, Uri via)\n+                : base(FramingUpgradeString.Negotiate, remoteAddress, via)\n+            {\n+                _parent = parent;\n+                _clientTokenProvider = TransportSecurityHelpers.GetSspiTokenProvider(\n+                    parent._securityTokenManager, remoteAddress, via, parent.Scheme, out _identityVerifier);\n+            }\n+\n+            internal override async Task OpenAsync(TimeSpan timeout)\n+            {\n+                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);\n+                base.Open(timeoutHelper.RemainingTime());\n+\n+                OutWrapper<TokenImpersonationLevel> impersonationLevelWrapper = new OutWrapper<TokenImpersonationLevel>();\n+                OutWrapper<bool> allowNtlmWrapper = new OutWrapper<bool>(); \n+                \n+                SecurityUtils.OpenTokenProviderIfRequired(_clientTokenProvider, timeoutHelper.RemainingTime());\n+                _credential = await TransportSecurityHelpers.GetSspiCredentialAsync(\n+                    _clientTokenProvider,\n+                    impersonationLevelWrapper,\n+                    allowNtlmWrapper,\n+                    timeoutHelper.GetCancellationToken());\n+\n+                _impersonationLevel = impersonationLevelWrapper.Value;\n+                _allowNtlm = allowNtlmWrapper; \n+\n+                return; \n+            }\n+\n+            internal override void Open(TimeSpan timeout)\n+            {\n+                OpenAsync(timeout).GetAwaiter();\n+            }\n+            \n+            internal override void Close(TimeSpan timeout)\n+            {\n+                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);\n+                base.Close(timeoutHelper.RemainingTime());\n+                SecurityUtils.CloseTokenProviderIfRequired(_clientTokenProvider, timeoutHelper.RemainingTime());\n+            }\n+\n+            static SecurityMessageProperty CreateServerSecurity(NegotiateStream negotiateStream)\n+            {\n+                GenericIdentity remoteIdentity = (GenericIdentity)negotiateStream.RemoteIdentity;\n+                string principalName = remoteIdentity.Name;\n+                if ((principalName != null) && (principalName.Length > 0))\n+                {\n+                    ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = SecurityUtils.CreatePrincipalNameAuthorizationPolicies(principalName);\n+                    SecurityMessageProperty result = new SecurityMessageProperty();\n+                    result.TransportToken = new SecurityTokenSpecification(null, authorizationPolicies);\n+                    result.ServiceSecurityContext = new ServiceSecurityContext(authorizationPolicies);\n+                    return result;\n+                }\n+                else\n+                {\n+                    return null;\n+                }\n+            }\n+\n+            protected override Stream OnInitiateUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity)\n+            {\n+                OutWrapper<SecurityMessageProperty> remoteSecurityOut = new OutWrapper<SecurityMessageProperty>(); \n+                \n+                var retVal = OnInitiateUpgradeAsync(stream, remoteSecurityOut).GetAwaiter().GetResult();\n+                remoteSecurity = remoteSecurityOut.Value;\n+\n+                return retVal;\n+            }\n+\n+            protected override Task<Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper<SecurityMessageProperty> remoteSecurity)\n+            {\n+                NegotiateStream negotiateStream;\n+                string targetName;\n+                EndpointIdentity identity;\n+\n+                if (TD.WindowsStreamSecurityOnInitiateUpgradeIsEnabled())\n+                {\n+                    TD.WindowsStreamSecurityOnInitiateUpgrade();\n+                }\n+\n+                // prepare\n+                InitiateUpgradePrepare(stream, out negotiateStream, out targetName, out identity);\n+\n+                // authenticate\n+                try\n+                {\n+                    negotiateStream.AuthenticateAsClient(_credential, targetName, _parent.ProtectionLevel, _impersonationLevel);","path":"src/System.Private.ServiceModel/src/System/ServiceModel/Channels/WindowsStreamSecurityUpgradeProvider.cs","position":362,"original_position":362,"commit_id":"f84ee4de9a75341512ffb1882badeb33f9b17668","original_commit_id":"f84ee4de9a75341512ffb1882badeb33f9b17668","user":{"login":"iamjasonp","id":1616847,"avatar_url":"https://avatars.githubusercontent.com/u/1616847?v=3","gravatar_id":"","url":"https://api.github.com/users/iamjasonp","html_url":"https://github.com/iamjasonp","followers_url":"https://api.github.com/users/iamjasonp/followers","following_url":"https://api.github.com/users/iamjasonp/following{/other_user}","gists_url":"https://api.github.com/users/iamjasonp/gists{/gist_id}","starred_url":"https://api.github.com/users/iamjasonp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iamjasonp/subscriptions","organizations_url":"https://api.github.com/users/iamjasonp/orgs","repos_url":"https://api.github.com/users/iamjasonp/repos","events_url":"https://api.github.com/users/iamjasonp/events{/privacy}","received_events_url":"https://api.github.com/users/iamjasonp/received_events","type":"User","site_admin":false},"body":"Ooh, good catch. This was supposed to have changed but I guess I missed it. ","created_at":"2015-12-01T09:17:48Z","updated_at":"2015-12-01T09:17:48Z","html_url":"https://github.com/dotnet/wcf/pull/550#discussion_r46254997","pull_request_url":"https://api.github.com/repos/dotnet/wcf/pulls/550","_links":{"self":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/comments/46254997"},"html":{"href":"https://github.com/dotnet/wcf/pull/550#discussion_r46254997"},"pull_request":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/550"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/wcf/pulls/550","id":52109914,"html_url":"https://github.com/dotnet/wcf/pull/550","diff_url":"https://github.com/dotnet/wcf/pull/550.diff","patch_url":"https://github.com/dotnet/wcf/pull/550.patch","issue_url":"https://api.github.com/repos/dotnet/wcf/issues/550","number":550,"state":"open","locked":false,"title":"Light up code for supporting Windows stream security","user":{"login":"iamjasonp","id":1616847,"avatar_url":"https://avatars.githubusercontent.com/u/1616847?v=3","gravatar_id":"","url":"https://api.github.com/users/iamjasonp","html_url":"https://github.com/iamjasonp","followers_url":"https://api.github.com/users/iamjasonp/followers","following_url":"https://api.github.com/users/iamjasonp/following{/other_user}","gists_url":"https://api.github.com/users/iamjasonp/gists{/gist_id}","starred_url":"https://api.github.com/users/iamjasonp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iamjasonp/subscriptions","organizations_url":"https://api.github.com/users/iamjasonp/orgs","repos_url":"https://api.github.com/users/iamjasonp/repos","events_url":"https://api.github.com/users/iamjasonp/events{/privacy}","received_events_url":"https://api.github.com/users/iamjasonp/received_events","type":"User","site_admin":false},"body":"The code still will not fully work yet as we are dependent on System.Net.Security.NegotiateStream being lit up. Once that is lit up we should be able to get to the inevitable other problems that will surface\r\n\r\nWe also yank the `includeWindowsGroups` as an option right now\r\n\r\nThe reenablement of tests and writing of them is being tracked on #301\r\n\r\nResolves #300","created_at":"2015-11-30T11:00:20Z","updated_at":"2015-12-01T09:17:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6b46c5aaf5ed5ac774a4222b300f32cc374bb993","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/wcf/pulls/550/commits","review_comments_url":"https://api.github.com/repos/dotnet/wcf/pulls/550/comments","review_comment_url":"https://api.github.com/repos/dotnet/wcf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/wcf/issues/550/comments","statuses_url":"https://api.github.com/repos/dotnet/wcf/statuses/f84ee4de9a75341512ffb1882badeb33f9b17668","head":{"label":"iamjasonp:negostream","ref":"negostream","sha":"f84ee4de9a75341512ffb1882badeb33f9b17668","user":{"login":"iamjasonp","id":1616847,"avatar_url":"https://avatars.githubusercontent.com/u/1616847?v=3","gravatar_id":"","url":"https://api.github.com/users/iamjasonp","html_url":"https://github.com/iamjasonp","followers_url":"https://api.github.com/users/iamjasonp/followers","following_url":"https://api.github.com/users/iamjasonp/following{/other_user}","gists_url":"https://api.github.com/users/iamjasonp/gists{/gist_id}","starred_url":"https://api.github.com/users/iamjasonp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iamjasonp/subscriptions","organizations_url":"https://api.github.com/users/iamjasonp/orgs","repos_url":"https://api.github.com/users/iamjasonp/repos","events_url":"https://api.github.com/users/iamjasonp/events{/privacy}","received_events_url":"https://api.github.com/users/iamjasonp/received_events","type":"User","site_admin":false},"repo":{"id":35954677,"name":"wcf","full_name":"iamjasonp/wcf","owner":{"login":"iamjasonp","id":1616847,"avatar_url":"https://avatars.githubusercontent.com/u/1616847?v=3","gravatar_id":"","url":"https://api.github.com/users/iamjasonp","html_url":"https://github.com/iamjasonp","followers_url":"https://api.github.com/users/iamjasonp/followers","following_url":"https://api.github.com/users/iamjasonp/following{/other_user}","gists_url":"https://api.github.com/users/iamjasonp/gists{/gist_id}","starred_url":"https://api.github.com/users/iamjasonp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iamjasonp/subscriptions","organizations_url":"https://api.github.com/users/iamjasonp/orgs","repos_url":"https://api.github.com/users/iamjasonp/repos","events_url":"https://api.github.com/users/iamjasonp/events{/privacy}","received_events_url":"https://api.github.com/users/iamjasonp/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/iamjasonp/wcf","description":"This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services.","fork":true,"url":"https://api.github.com/repos/iamjasonp/wcf","forks_url":"https://api.github.com/repos/iamjasonp/wcf/forks","keys_url":"https://api.github.com/repos/iamjasonp/wcf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/iamjasonp/wcf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/iamjasonp/wcf/teams","hooks_url":"https://api.github.com/repos/iamjasonp/wcf/hooks","issue_events_url":"https://api.github.com/repos/iamjasonp/wcf/issues/events{/number}","events_url":"https://api.github.com/repos/iamjasonp/wcf/events","assignees_url":"https://api.github.com/repos/iamjasonp/wcf/assignees{/user}","branches_url":"https://api.github.com/repos/iamjasonp/wcf/branches{/branch}","tags_url":"https://api.github.com/repos/iamjasonp/wcf/tags","blobs_url":"https://api.github.com/repos/iamjasonp/wcf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/iamjasonp/wcf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/iamjasonp/wcf/git/refs{/sha}","trees_url":"https://api.github.com/repos/iamjasonp/wcf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/iamjasonp/wcf/statuses/{sha}","languages_url":"https://api.github.com/repos/iamjasonp/wcf/languages","stargazers_url":"https://api.github.com/repos/iamjasonp/wcf/stargazers","contributors_url":"https://api.github.com/repos/iamjasonp/wcf/contributors","subscribers_url":"https://api.github.com/repos/iamjasonp/wcf/subscribers","subscription_url":"https://api.github.com/repos/iamjasonp/wcf/subscription","commits_url":"https://api.github.com/repos/iamjasonp/wcf/commits{/sha}","git_commits_url":"https://api.github.com/repos/iamjasonp/wcf/git/commits{/sha}","comments_url":"https://api.github.com/repos/iamjasonp/wcf/comments{/number}","issue_comment_url":"https://api.github.com/repos/iamjasonp/wcf/issues/comments{/number}","contents_url":"https://api.github.com/repos/iamjasonp/wcf/contents/{+path}","compare_url":"https://api.github.com/repos/iamjasonp/wcf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/iamjasonp/wcf/merges","archive_url":"https://api.github.com/repos/iamjasonp/wcf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/iamjasonp/wcf/downloads","issues_url":"https://api.github.com/repos/iamjasonp/wcf/issues{/number}","pulls_url":"https://api.github.com/repos/iamjasonp/wcf/pulls{/number}","milestones_url":"https://api.github.com/repos/iamjasonp/wcf/milestones{/number}","notifications_url":"https://api.github.com/repos/iamjasonp/wcf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/iamjasonp/wcf/labels{/name}","releases_url":"https://api.github.com/repos/iamjasonp/wcf/releases{/id}","created_at":"2015-05-20T14:54:42Z","updated_at":"2015-05-20T14:54:44Z","pushed_at":"2015-11-30T10:57:24Z","git_url":"git://github.com/iamjasonp/wcf.git","ssh_url":"git@github.com:iamjasonp/wcf.git","clone_url":"https://github.com/iamjasonp/wcf.git","svn_url":"https://github.com/iamjasonp/wcf","homepage":"","size":4269,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"b2f2e49aade3ce1f4435b749dac780d78ce49092","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":35562993,"name":"wcf","full_name":"dotnet/wcf","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/wcf","description":"This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services.","fork":false,"url":"https://api.github.com/repos/dotnet/wcf","forks_url":"https://api.github.com/repos/dotnet/wcf/forks","keys_url":"https://api.github.com/repos/dotnet/wcf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/wcf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/wcf/teams","hooks_url":"https://api.github.com/repos/dotnet/wcf/hooks","issue_events_url":"https://api.github.com/repos/dotnet/wcf/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/wcf/events","assignees_url":"https://api.github.com/repos/dotnet/wcf/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/wcf/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/wcf/tags","blobs_url":"https://api.github.com/repos/dotnet/wcf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/wcf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/wcf/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/wcf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/wcf/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/wcf/languages","stargazers_url":"https://api.github.com/repos/dotnet/wcf/stargazers","contributors_url":"https://api.github.com/repos/dotnet/wcf/contributors","subscribers_url":"https://api.github.com/repos/dotnet/wcf/subscribers","subscription_url":"https://api.github.com/repos/dotnet/wcf/subscription","commits_url":"https://api.github.com/repos/dotnet/wcf/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/wcf/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/wcf/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/wcf/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/wcf/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/wcf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/wcf/merges","archive_url":"https://api.github.com/repos/dotnet/wcf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/wcf/downloads","issues_url":"https://api.github.com/repos/dotnet/wcf/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/wcf/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/wcf/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/wcf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/wcf/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/wcf/releases{/id}","created_at":"2015-05-13T17:17:03Z","updated_at":"2015-11-30T07:25:19Z","pushed_at":"2015-12-01T05:15:53Z","git_url":"git://github.com/dotnet/wcf.git","ssh_url":"git@github.com:dotnet/wcf.git","clone_url":"https://github.com/dotnet/wcf.git","svn_url":"https://github.com/dotnet/wcf","homepage":"","size":4666,"stargazers_count":537,"watchers_count":537,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":170,"mirror_url":null,"open_issues_count":111,"forks":170,"open_issues":111,"watchers":537,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/550"},"html":{"href":"https://github.com/dotnet/wcf/pull/550"},"issue":{"href":"https://api.github.com/repos/dotnet/wcf/issues/550"},"comments":{"href":"https://api.github.com/repos/dotnet/wcf/issues/550/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/550/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/wcf/pulls/550/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/wcf/statuses/f84ee4de9a75341512ffb1882badeb33f9b17668"}}}}