<div dir="ltr"><div dir="ltr">Hello, Alex,<div><br></div><div>I have posted a PR: <a href="https://github.com/squid-cache/squid/pull/1597">https://github.com/squid-cache/squid/pull/1597</a></div><div><br></div><div>This is my first contribution to open source. Could you please verify if everything is OK.</div><div><br></div><div>Kind regards,</div><div>    Ankor.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">чт, 16 нояб. 2023 г. в 17:01, Alex Rousskov <<a href="mailto:rousskov@measurement-factory.com">rousskov@measurement-factory.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 2023-11-16 07:48, Andrey K wrote:<br>
<br>
> I have slightly patched the negotiate_kerberos_pac.cc to <br>
> implement ResourceGropIds-block parsing.<br>
<br>
Please consider posting tested changes as a GitHub Pull Request:<br>
<a href="https://wiki.squid-cache.org/MergeProcedure#pull-request" rel="noreferrer" target="_blank">https://wiki.squid-cache.org/MergeProcedure#pull-request</a><br>
<br>
<br>
Thank you,<br>
<br>
Alex.<br>
<br>
<br>
> Maybe it will be useful for the community.<br>
> This patch can be included in future Squid-releases.<br>
> <br>
> Kind regards,<br>
>     Ankor.<br>
> <br>
> The patch for the <br>
> file src/auth/negotiate/kerberos/negotiate_kerberos_pac.cc below:<br>
> <br>
> @@ -362,6 +362,123 @@<br>
>       return ad_groups;<br>
>   }<br>
> <br>
> +<br>
> +char *<br>
> +get_resource_group_domain_sid(uint32_t ResourceGroupDomainSid){<br>
> +<br>
> +    if (ResourceGroupDomainSid!= 0) {<br>
> +        uint8_t rev;<br>
> +        uint64_t idauth;<br>
> +        char dli[256];<br>
> +        char *ag;<br>
> +        int l;<br>
> +<br>
> +        align(4);<br>
> +<br>
> +        uint32_t nauth = get4byt();<br>
> +<br>
> +        size_t length = 1+1+6+nauth*4;<br>
> +<br>
> +            ag=(char *)xcalloc((length+1)*sizeof(char),1);<br>
> +            // the first byte is a length of the SID<br>
> +            ag[0] = (char) length;<br>
> +            memcpy((void *)&ag[1],(const void*)&p[bpos],1);<br>
> +            memcpy((void *)&ag[2],(const void*)&p[bpos+1],1);<br>
> +            ag[2] = ag[2]+1;<br>
> +            memcpy((void *)&ag[3],(const void*)&p[bpos+2],6+nauth*4);<br>
> +<br>
> +<br>
> +<br>
> +        /* mainly for debug only */<br>
> +        rev = get1byt();<br>
> +        bpos = bpos + 1; /*nsub*/<br>
> +        idauth = get6byt_be();<br>
> +<br>
> +        snprintf(dli,sizeof(dli),"S-%d-%lu",rev,(long unsigned int)idauth);<br>
> +        for ( l=0; l<(int)nauth; l++ ) {<br>
> +            uint32_t sauth;<br>
> +            sauth = get4byt();<br>
> +            snprintf((char <br>
> *)&dli[strlen(dli)],sizeof(dli)-strlen(dli),"-%u",sauth);<br>
> +        }<br>
> +        debug((char *) "%s| %s: INFO: Got ResourceGroupDomainSid %s\n", <br>
> LogTime(), PROGRAM, dli);<br>
> +        return ag;<br>
> +    }<br>
> +<br>
> +    return NULL;<br>
> +}<br>
> +<br>
> +char *<br>
> +get_resource_groups(char *ad_groups, char *resource_group_domain_sid, <br>
> uint32_t ResourceGroupIds, uint32_t ResourceGroupCount){<br>
> +    size_t group_domain_sid_len = resource_group_domain_sid[0];<br>
> +    char *ag;<br>
> +    size_t length;<br>
> +<br>
> +    resource_group_domain_sid++; //now it points to the actual data<br>
> +<br>
> +<br>
> +    if (ResourceGroupIds!= 0) {<br>
> +        uint32_t ngroup;<br>
> +        int l;<br>
> +<br>
> +        align(4);<br>
> +        ngroup = get4byt();<br>
> +        if ( ngroup != ResourceGroupCount) {<br>
> +            debug((char *) "%s| %s: ERROR: Group encoding error => <br>
> ResourceGroupCount: %d Array size: %d\n",<br>
> +                  LogTime(), PROGRAM, ResourceGroupCount, ngroup);<br>
> +            return NULL;<br>
> +        }<br>
> +        debug((char *) "%s| %s: INFO: Found %d Resource Group rids\n", <br>
> LogTime(), PROGRAM, ResourceGroupCount);<br>
> +<br>
> +        //make a group template which begins with the ResourceGroupDomainID<br>
> +        length = group_domain_sid_len+4;  //+4 for a rid<br>
> +        ag=(char *)xcalloc(length*sizeof(char),1);<br>
> +        memcpy((void *)ag,(const void*)resource_group_domain_sid, <br>
> group_domain_sid_len);<br>
> +<br>
> +<br>
> +        for ( l=0; l<(int)ResourceGroupCount; l++) {<br>
> +            uint32_t sauth;<br>
> +            memcpy((void *)&ag[group_domain_sid_len],(const <br>
> void*)&p[bpos],4);<br>
> +<br>
> +            if (!pstrcat(ad_groups," group=")) {<br>
> +                debug((char *) "%s| %s: WARN: Too many groups ! size > <br>
> %d : %s\n",<br>
> +                      LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);<br>
> +               xfree(ag);<br>
> +               return NULL;<br>
> +            }<br>
> +<br>
> +<br>
> +            struct base64_encode_ctx ctx;<br>
> +            base64_encode_init(&ctx);<br>
> +            const uint32_t expectedSz = base64_encode_len(length) +1 /* <br>
> terminator */;<br>
> +            char *b64buf = static_cast<char *>(xcalloc(expectedSz, 1));<br>
> +            size_t blen = base64_encode_update(&ctx, b64buf, length, <br>
> reinterpret_cast<uint8_t*>(ag));<br>
> +            blen += base64_encode_final(&ctx, b64buf+blen);<br>
> +            b64buf[expectedSz-1] = '\0';<br>
> +            if (!pstrcat(ad_groups, reinterpret_cast<char*>(b64buf))) {<br>
> +                debug((char *) "%s| %s: WARN: Too many groups ! size > <br>
> %d : %s\n",<br>
> +                      LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);<br>
> +               xfree(ag);<br>
> +               xfree(b64buf);<br>
> +               return NULL;<br>
> +            }<br>
> +            xfree(b64buf);<br>
> +<br>
> +<br>
> +<br>
> +            sauth = get4byt();<br>
> +            debug((char *) "%s| %s: Info: Got rid: %u\n", LogTime(), <br>
> PROGRAM, sauth);<br>
> +            /* attribute */<br>
> +            bpos = bpos+4;<br>
> +        }<br>
> +<br>
> +        xfree(ag);<br>
> +       return ad_groups;<br>
> +    }<br>
> +<br>
> +    return NULL;<br>
> +}<br>
> +<br>
> +<br>
>   char *<br>
>   get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac)<br>
>   {<br>
> @@ -379,14 +496,14 @@<br>
>       uint32_t LogonDomainId=0;<br>
>       uint32_t SidCount=0;<br>
>       uint32_t ExtraSids=0;<br>
> -    /*<br>
>       uint32_t ResourceGroupDomainSid=0;<br>
>       uint32_t ResourceGroupCount=0;<br>
>       uint32_t ResourceGroupIds=0;<br>
> -    */<br>
>       char **Rids=NULL;<br>
>       int l=0;<br>
> <br>
> +    char * resource_group_domain_sid=NULL;<br>
> +<br>
>       if (!ad_groups) {<br>
>           debug((char *) "%s| %s: ERR: No space to store groups\n",<br>
>                 LogTime(), PROGRAM);<br>
> @@ -454,11 +571,11 @@<br>
>       bpos = bpos+40;<br>
>       SidCount = get4byt();<br>
>       ExtraSids = get4byt();<br>
> -    /* 4 bytes ResourceGroupDomainSid<br>
> -     * 4 bytes ResourceGroupCount<br>
> -     * 4 bytes ResourceGroupIds<br>
> -     */<br>
> -    bpos = bpos+12;<br>
> +<br>
> +    ResourceGroupDomainSid = get4byt();<br>
> +    ResourceGroupCount = get4byt();<br>
> +    ResourceGroupIds = get4byt();<br>
> +<br>
>       /*<br>
>        * Read all data from structure => Now check pointers<br>
>        */<br>
> @@ -483,7 +600,15 @@<br>
>       if ((ad_groups = getextrasids(ad_groups,ExtraSids,SidCount))==NULL)<br>
>           goto k5clean;<br>
> <br>
> +    resource_group_domain_sid = <br>
> get_resource_group_domain_sid(ResourceGroupDomainSid);<br>
> +    if(resource_group_domain_sid && ResourceGroupCount && <br>
> ResourceGroupIds){<br>
> +        get_resource_groups(ad_groups, resource_group_domain_sid, <br>
> ResourceGroupIds, ResourceGroupCount);<br>
> +    }<br>
> +<br>
>       debug((char *) "%s| %s: INFO: Read %d of %d bytes \n", LogTime(), <br>
> PROGRAM, bpos, (int)ad_data->length);<br>
> +<br>
> +    if(resource_group_domain_sid) xfree(resource_group_domain_sid);<br>
> +<br>
>       if (Rids) {<br>
>           for ( l=0; l<(int)GroupCount; l++) {<br>
>               xfree(Rids[l]);<br>
> @@ -493,6 +618,8 @@<br>
>       krb5_free_data(context, ad_data);<br>
>       return ad_groups;<br>
>   k5clean:<br>
> +    if(resource_group_domain_sid) xfree(resource_group_domain_sid);<br>
> +<br>
>       if (Rids) {<br>
>           for ( l=0; l<(int)GroupCount; l++) {<br>
>               xfree(Rids[l]);<br>
> <br>
> _______________________________________________<br>
> squid-users mailing list<br>
> <a href="mailto:squid-users@lists.squid-cache.org" target="_blank">squid-users@lists.squid-cache.org</a><br>
> <a href="https://lists.squid-cache.org/listinfo/squid-users" rel="noreferrer" target="_blank">https://lists.squid-cache.org/listinfo/squid-users</a><br>
<br>
_______________________________________________<br>
squid-users mailing list<br>
<a href="mailto:squid-users@lists.squid-cache.org" target="_blank">squid-users@lists.squid-cache.org</a><br>
<a href="https://lists.squid-cache.org/listinfo/squid-users" rel="noreferrer" target="_blank">https://lists.squid-cache.org/listinfo/squid-users</a><br>
</blockquote></div></div>