<commit_before>﻿using System;
using System.DirectoryServices.AccountManagement;
using System.Security.Principal;
using System.ServiceModel;
using TGServiceInterface;

namespace TGServerService
{
    //note this only works with MACHINE LOCAL groups and admins for now
    //if someone wants AD shit, code it yourself
    partial class TGStationServer : ServiceAuthorizationManager, ITGAdministration
    {
        SecurityIdentifier TheDroidsWereLookingFor;
        object authLock = new object();
        string LastSeenUser = null;

        readonly SecurityIdentifier ServiceSID = UserPrincipal.Current.Sid;

        /// <inheritdoc />
        public string GetCurrentAuthorizedGroup()
        {
            try
            {
                if (TheDroidsWereLookingFor == null)
                    return "ADMIN";

                var pc = new PrincipalContext(ContextType.Machine);
                return GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value).Name;
            }
            catch
            {
                return null;
            }
        }

        /// <inheritdoc />
        public string SetAuthorizedGroup(string groupName)
        {
            if (groupName == null)
            {
                TheDroidsWereLookingFor = null;
                var config = Properties.Settings.Default;
                config.AuthorizedGroupSID = null;
                config.Save();
                return "ADMIN";
            }
            return FindTheDroidsWereLookingFor(groupName);
        }

        string FindTheDroidsWereLookingFor(string search = null)
        {
            //find the group that is authorized to use the tools
            var pc = new PrincipalContext(ContextType.Machine);
            var config = Properties.Settings.Default;
            var groupName = search ?? config.AuthorizedGroupSID;
            if (String.IsNullOrWhiteSpace(groupName))
                return null;
            var gp = GroupPrincipal.FindByIdentity(pc, search != null ? IdentityType.Name : IdentityType.Sid, groupName);
            if (gp == null)
            {
                if (search != null)
                    //try again with all types
                    gp = GroupPrincipal.FindByIdentity(pc, search);
                if (gp == null)
                    return null;
            }
            TheDroidsWereLookingFor = gp.Sid;
            if (search != null)
            {
                config.AuthorizedGroupSID = TheDroidsWereLookingFor.Value;
                config.Save();
            }
            return gp.Name;
        }

        static UserPrincipal WindowsIdentityToUserPrincipal(WindowsIdentity windowsIdent, out PrincipalContext pc)
        {
            pc = new PrincipalContext(ContextType.Machine);
            var up = UserPrincipal.FindByIdentity(pc, IdentityType.Sid, windowsIdent.User.Value);
            //tiny bit of ad support here just cause i was debugging at work
            //if up is null check it on a domain
            if (up == null)
                try
                {
                    up = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), IdentityType.Sid, windowsIdent.User.Value);
                }
                catch { }
            return up;
        }

        //This function checks for authorization whenever an API call is made
        //This does NOT validate the windows account, that is done when the user connects internally
        protected override bool CheckAccessCore(OperationContext operationContext)
        {
            if (operationContext.EndpointDispatcher.ContractName == typeof(ITGConnectivity).Name)   //always allow connectivity checks
                return true;

            var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity;
            var wp = new WindowsPrincipal(windowsIdent);

            bool authSuccess;
            var isInterop = operationContext.EndpointDispatcher.ContractName == typeof(ITGInterop).Name;
            if (isInterop)
            {
                //only DD is allowed to use Interop
                //make sure it's from the same windows account
                var up = WindowsIdentityToUserPrincipal(windowsIdent, out PrincipalContext pc);
                authSuccess = up.Sid != ServiceSID;
            }
            else
                //first allow admins
                authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator);

            //if we're not an admin, check that we aren't trying to access the admin interface
            if (!authSuccess && operationContext.EndpointDispatcher.ContractName != typeof(ITGAdministration).Name && TheDroidsWereLookingFor != null)
            {
                var up = WindowsIdentityToUserPrincipal(windowsIdent, out PrincipalContext pc);
                if (up != null)
                {
                    var gp = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value);
                    if (gp != null)
                    {
                        //and allow those in the authorized group
                        authSuccess = up.IsMemberOf(gp);
                    }
                }
            }
            if (!isInterop)
                lock (authLock)
                {
                    var user = operationContext.ServiceSecurityContext.WindowsIdentity.Name;
                    if (LastSeenUser != user)
                    {
                        LastSeenUser = user;
                        TGServerService.WriteAccess(user, authSuccess);
                    }
                }
            return authSuccess;
        }

        /// <inheritdoc />
        public ushort RemoteAccessPort()
        {
            return Properties.Settings.Default.RemoteAccessPort;
        }

        /// <inheritdoc />
        public string SetRemoteAccessPort(ushort port)
        {
            if (port == 0)
                return "Cannot bind to port 0";
            var Config = Properties.Settings.Default;
            Config.RemoteAccessPort = port;
            Config.Save();
            return null;
        }
    }
}
<commit_msg>TIL that WindowsIdentity DOES contain the Sid. It just has a cryptic ass name<commit_after>﻿using System;
using System.DirectoryServices.AccountManagement;
using System.Security.Principal;
using System.ServiceModel;
using TGServiceInterface;

namespace TGServerService
{
    //note this only works with MACHINE LOCAL groups and admins for now
    //if someone wants AD shit, code it yourself
    partial class TGStationServer : ServiceAuthorizationManager, ITGAdministration
    {
        SecurityIdentifier TheDroidsWereLookingFor;
        object authLock = new object();
        string LastSeenUser = null;

        readonly SecurityIdentifier ServiceSID = WindowsIdentity.GetCurrent().User;

        /// <inheritdoc />
        public string GetCurrentAuthorizedGroup()
        {
            try
            {
                if (TheDroidsWereLookingFor == null)
                    return "ADMIN";

                var pc = new PrincipalContext(ContextType.Machine);
                return GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, TheDroidsWereLookingFor.Value).Name;
            }
            catch
            {
                return null;
            }
        }

        /// <inheritdoc />
        public string SetAuthorizedGroup(string groupName)
        {
            if (groupName == null)
            {
                TheDroidsWereLookingFor = null;
                var config = Properties.Settings.Default;
                config.AuthorizedGroupSID = null;
                config.Save();
                return "ADMIN";
            }
            return FindTheDroidsWereLookingFor(groupName);
        }

        string FindTheDroidsWereLookingFor(string search = null)
        {
            //find the group that is authorized to use the tools
            var pc = new PrincipalContext(ContextType.Machine);
            var config = Properties.Settings.Default;
            var groupName = search ?? config.AuthorizedGroupSID;
            if (String.IsNullOrWhiteSpace(groupName))
                return null;
            var gp = GroupPrincipal.FindByIdentity(pc, search != null ? IdentityType.Name : IdentityType.Sid, groupName);
            if (gp == null)
            {
                if (search != null)
                    //try again with all types
                    gp = GroupPrincipal.FindByIdentity(pc, search);
                if (gp == null)
                    return null;
            }
            TheDroidsWereLookingFor = gp.Sid;
            if (search != null)
            {
                config.AuthorizedGroupSID = TheDroidsWereLookingFor.Value;
                config.Save();
            }
            return gp.Name;
        }

		//This function checks for authorization whenever an API call is made
		//This does NOT validate the windows account, that is done when the user connects internally
		protected override bool CheckAccessCore(OperationContext operationContext)
		{
			var contract = operationContext.EndpointDispatcher.ContractName;

			if (contract == typeof(ITGConnectivity).Name)   //always allow connectivity checks
				return true;

			var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity;

			if (contract == typeof(ITGInterop).Name)	//only allow the same user the service is running as to use interop, because that's what DD is running as
				return windowsIdent.User == ServiceSID;

			var wp = new WindowsPrincipal(windowsIdent);
			//first allow admins
			var authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator);

			//if we're not an admin, check that we aren't trying to access the admin interface
			if (!authSuccess && operationContext.EndpointDispatcher.ContractName != typeof(ITGAdministration).Name && TheDroidsWereLookingFor != null)
				authSuccess = wp.IsInRole(new SecurityIdentifier(Properties.Settings.Default.AuthorizedGroupSID));

			lock (authLock)
			{
				var user = windowsIdent.Name;
				if (LastSeenUser != user)
				{
					LastSeenUser = user;
					TGServerService.WriteAccess(user, authSuccess);
				}
			}
			return authSuccess;
		}

        /// <inheritdoc />
        public ushort RemoteAccessPort()
        {
            return Properties.Settings.Default.RemoteAccessPort;
        }

        /// <inheritdoc />
        public string SetRemoteAccessPort(ushort port)
        {
            if (port == 0)
                return "Cannot bind to port 0";
            var Config = Properties.Settings.Default;
            Config.RemoteAccessPort = port;
            Config.Save();
            return null;
        }
    }
}

{'fraction_non_alphanumeric': 0.07166215079884145, 'fraction_numerical': 0.0003737269924320284, 'mean_word_length': 1.7723387723387722, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '647796', 'n_tokens_mistral': 2745, 'n_tokens_neox': 2468, 'n_words': 702}