26. Araxis Merge File Comparison Report

Produced by Araxis Merge on 11/20/2017 2:16:17 PM GMT Standard Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

26.1 Files compared

# Location File Last Modified
1 C:\Merge Test Files\8.0.47\java\org\apache\catalina\authenticator SpnegoAuthenticator.java Fri Sep 29 16:53:28 2017 UTC
2 C:\Merge Test Files\8.5.23\java\org\apache\catalina\authenticator SpnegoAuthenticator.java Thu Sep 28 11:32:16 2017 UTC

26.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 14 968
Changed 12 24
Inserted 1 1
Removed 0 0

26.3 Comparison options

Whitespace Consecutive whitespace is treated as a single space
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

26.4 Active regular expressions

No regular expressions were active.

26.5 Comparison detail

1   /*   1   /*
2    * License d to the A pache Soft ware Found ation (ASF ) under on e or more   2    * License d to the A pache Soft ware Found ation (ASF ) under on e or more
3    * contrib utor licen se agreeme nts.  See  the NOTICE  file dist ributed wi th   3    * contrib utor licen se agreeme nts.  See  the NOTICE  file dist ributed wi th
4    * this wo rk for add itional in formation  regarding  copyright  ownership.   4    * this wo rk for add itional in formation  regarding  copyright  ownership.
5    * The ASF  licenses  this file  to You und er the Apa che Licens e, Version  2.0   5    * The ASF  licenses  this file  to You und er the Apa che Licens e, Version  2.0
6    * (the "L icense");  you may no t use this  file exce pt in comp liance wit h   6    * (the "L icense");  you may no t use this  file exce pt in comp liance wit h
7    * the Lic ense.  You  may obtai n a copy o f the Lice nse at   7    * the Lic ense.  You  may obtai n a copy o f the Lice nse at
8    *   8    *
9    *      ht tp://www.a pache.org/ licenses/L ICENSE-2.0   9    *      ht tp://www.a pache.org/ licenses/L ICENSE-2.0
10    *   10    *
11    * Unless  required b y applicab le law or  agreed to  in writing , software   11    * Unless  required b y applicab le law or  agreed to  in writing , software
12    * distrib uted under  the Licen se is dist ributed on  an "AS IS " BASIS,   12    * distrib uted under  the Licen se is dist ributed on  an "AS IS " BASIS,
13    * WITHOUT  WARRANTIE S OR CONDI TIONS OF A NY KIND, e ither expr ess or imp lied.   13    * WITHOUT  WARRANTIE S OR CONDI TIONS OF A NY KIND, e ither expr ess or imp lied.
14    * See the  License f or the spe cific lang uage gover ning permi ssions and   14    * See the  License f or the spe cific lang uage gover ning permi ssions and
15    * limitat ions under  the Licen se.   15    * limitat ions under  the Licen se.
16    */   16    */
17   package or g.apache.c atalina.au thenticato r;   17   package or g.apache.c atalina.au thenticato r;
18     18  
19   import jav a.io.File;   19   import jav a.io.File;
20   import jav a.io.IOExc eption;   20   import jav a.io.IOExc eption;
21   import jav a.security .Principal ;   21   import jav a.security .Principal ;
22   import jav a.security .Privilege dAction;   22   import jav a.security .Privilege dAction;
23   import jav a.security .Privilege dActionExc eption;   23   import jav a.security .Privilege dActionExc eption;
24   import jav a.security .Privilege dException Action;   24   import jav a.security .Privilege dException Action;
25   import jav a.util.Lin kedHashMap ;   25   import jav a.util.Lin kedHashMap ;
26   import jav a.util.reg ex.Pattern ;   26   import jav a.util.reg ex.Pattern ;
27     27  
28   import jav ax.securit y.auth.Sub ject;   28   import jav ax.securit y.auth.Sub ject;
29   import jav ax.securit y.auth.log in.LoginCo ntext;   29   import jav ax.securit y.auth.log in.LoginCo ntext;
30   import jav ax.securit y.auth.log in.LoginEx ception;   30   import jav ax.securit y.auth.log in.LoginEx ception;
31   import jav ax.servlet .http.Http ServletRes ponse;   31   import jav ax.servlet .http.Http ServletRes ponse;
32     32  
33   import org .apache.ca talina.Lif ecycleExce ption;   33   import org .apache.ca talina.Lif ecycleExce ption;
34   import org .apache.ca talina.Rea lm;   34   import org .apache.ca talina.Rea lm;
35   import org .apache.ca talina.con nector.Req uest;   35   import org .apache.ca talina.con nector.Req uest;
36   import org .apache.ju li.logging .Log;   36   import org .apache.ju li.logging .Log;
37   import org .apache.ju li.logging .LogFactor y;   37   import org .apache.ju li.logging .LogFactor y;
38   import org .apache.to mcat.util. buf.ByteCh unk;   38   import org .apache.to mcat.util. buf.ByteCh unk;
39   import org .apache.to mcat.util. buf.Messag eBytes;   39   import org .apache.to mcat.util. buf.Messag eBytes;
40   import org .apache.to mcat.util. codec.bina ry.Base64;   40   import org .apache.to mcat.util. codec.bina ry.Base64;
41   import org .apache.to mcat.util. compat.Jre Vendor;   41   import org .apache.to mcat.util. compat.Jre Vendor;
42   import org .ietf.jgss .GSSContex t;   42   import org .ietf.jgss .GSSContex t;
43   import org .ietf.jgss .GSSCreden tial;   43   import org .ietf.jgss .GSSCreden tial;
44   import org .ietf.jgss .GSSExcept ion;   44   import org .ietf.jgss .GSSExcept ion;
45   import org .ietf.jgss .GSSManage r;   45   import org .ietf.jgss .GSSManage r;
46   import org .ietf.jgss .Oid;   46   import org .ietf.jgss .Oid;
47     47  
48     48  
49   /**   49   /**
50    * A SPNEG O authenti cator that  uses the  SPNEGO/Ker beros supp ort built  in to Java   50    * A SPNEG O authenti cator that  uses the  SPNEGO/Ker beros supp ort built  in to Java
51    * 6. Succ essful Ker beros auth entication  depends o n the corr ect config uration of   51    * 6. Succ essful Ker beros auth entication  depends o n the corr ect config uration of
52    * multipl e componen ts. If the  configura tion is in valid, the  error mes sages are   52    * multipl e componen ts. If the  configura tion is in valid, the  error mes sages are
53    * often c ryptic alt hough a Go ogle searc h will usu ally point  you in th e right   53    * often c ryptic alt hough a Go ogle searc h will usu ally point  you in th e right
54    * directi on.   54    * directi on.
55    */   55    */
56   public cla ss SpnegoA uthenticat or extends  Authentic atorBase {   56   public cla ss SpnegoA uthenticat or extends  Authentic atorBase {
57     57  
58       privat e static f inal Log l og = LogFa ctory.getL og(SpnegoA uthenticat or.class);   58       privat e static f inal Log l og = LogFa ctory.getL og(SpnegoA uthenticat or.class);
        59       privat e static f inal Strin g AUTH_HEA DER_VALUE_ NEGOTIATE  = "Negotia te";
59     60  
60       privat e String l oginConfig Name = Con stants.DEF AULT_LOGIN _MODULE_NA ME;   61       privat e String l oginConfig Name = Con stants.DEF AULT_LOGIN _MODULE_NA ME;
61       public  String ge tLoginConf igName() {   62       public  String ge tLoginConf igName() {
62           re turn login ConfigName ;   63           re turn login ConfigName ;
63       }   64       }
64       public  void setL oginConfig Name(Strin g loginCon figName) {   65       public  void setL oginConfig Name(Strin g loginCon figName) {
65           th is.loginCo nfigName =  loginConf igName;   66           th is.loginCo nfigName =  loginConf igName;
66       }   67       }
67     68  
68       privat e boolean  storeDeleg atedCreden tial = tru e;   69       privat e boolean  storeDeleg atedCreden tial = tru e;
69       public  boolean i sStoreDele gatedCrede ntial() {   70       public  boolean i sStoreDele gatedCrede ntial() {
70           re turn store DelegatedC redential;   71           re turn store DelegatedC redential;
71       }   72       }
72       public  void setS toreDelega tedCredent ial(   73       public  void setS toreDelega tedCredent ial(
73                boolean  storeDeleg atedCreden tial) {   74                boolean  storeDeleg atedCreden tial) {
74           th is.storeDe legatedCre dential =  storeDeleg atedCreden tial;   75           th is.storeDe legatedCre dential =  storeDeleg atedCreden tial;
75       }   76       }
76     77  
77       privat e Pattern  noKeepAliv eUserAgent s = null;   78       privat e Pattern  noKeepAliv eUserAgent s = null;
78       public  String ge tNoKeepAli veUserAgen ts() {   79       public  String ge tNoKeepAli veUserAgen ts() {
79           Pa ttern p =  noKeepAliv eUserAgent s;   80           Pa ttern p =  noKeepAliv eUserAgent s;
80           if  (p == nul l) {   81           if  (p == nul l) {
81                return n ull;   82                return n ull;
82           }  else {   83           }  else {
83                return p .pattern() ;   84                return p .pattern() ;
84           }   85           }
85       }   86       }
86       public  void setN oKeepAlive UserAgents (String no KeepAliveU serAgents)  {   87       public  void setN oKeepAlive UserAgents (String no KeepAliveU serAgents)  {
87           if  (noKeepAl iveUserAge nts == nul l ||   88           if  (noKeepAl iveUserAge nts == nul l ||
88                    noKe epAliveUse rAgents.le ngth() ==  0) {   89                    noKe epAliveUse rAgents.le ngth() ==  0) {
89                this.noK eepAliveUs erAgents =  null;   90                this.noK eepAliveUs erAgents =  null;
90           }  else {   91           }  else {
91                this.noK eepAliveUs erAgents =  Pattern.c ompile(noK eepAliveUs erAgents);   92                this.noK eepAliveUs erAgents =  Pattern.c ompile(noK eepAliveUs erAgents);
92           }   93           }
93       }   94       }
94     95  
95       privat e boolean  applyJava8 u40Fix = t rue;   96       privat e boolean  applyJava8 u40Fix = t rue;
96       public  boolean g etApplyJav a8u40Fix()  {   97       public  boolean g etApplyJav a8u40Fix()  {
97           re turn apply Java8u40Fi x;   98           re turn apply Java8u40Fi x;
98       }   99       }
99       public  void setA pplyJava8u 40Fix(bool ean applyJ ava8u40Fix ) {   100       public  void setA pplyJava8u 40Fix(bool ean applyJ ava8u40Fix ) {
100           th is.applyJa va8u40Fix  = applyJav a8u40Fix;   101           th is.applyJa va8u40Fix  = applyJav a8u40Fix;
101       }   102       }
102     103  
103     104  
104       @Overr ide   105       @Overr ide
105       protec ted String  getAuthMe thod() {   106       protec ted String  getAuthMe thod() {
106           re turn Const ants.SPNEG O_METHOD;   107           re turn Const ants.SPNEG O_METHOD;
107       }   108       }
108     109  
109     110  
110       @Overr ide   111       @Overr ide
111       protec ted void i nitInterna l() throws  Lifecycle Exception  {   112       protec ted void i nitInterna l() throws  Lifecycle Exception  {
112           su per.initIn ternal();   113           su per.initIn ternal();
113     114  
114           //  Kerberos  configurat ion file l ocation   115           //  Kerberos  configurat ion file l ocation
115           St ring krb5C onf = Syst em.getProp erty(Const ants.KRB5_ CONF_PROPE RTY);   116           St ring krb5C onf = Syst em.getProp erty(Const ants.KRB5_ CONF_PROPE RTY);
116           if  (krb5Conf  == null)  {   117           if  (krb5Conf  == null)  {
117                // Syste m property  not set,  use the To mcat defau lt   118                // Syste m property  not set,  use the To mcat defau lt
118                File krb 5ConfFile  = new File (container .getCatali naBase(),   119                File krb 5ConfFile  = new File (container .getCatali naBase(),
119                         Constants. DEFAULT_KR B5_CONF);   120                         Constants. DEFAULT_KR B5_CONF);
120                System.s etProperty (Constants .KRB5_CONF _PROPERTY,   121                System.s etProperty (Constants .KRB5_CONF _PROPERTY,
121                         krb5ConfFi le.getAbso lutePath() );   122                         krb5ConfFi le.getAbso lutePath() );
122           }   123           }
123     124  
124           //  JAAS conf iguration  file locat ion   125           //  JAAS conf iguration  file locat ion
125           St ring jaasC onf = Syst em.getProp erty(Const ants.JAAS_ CONF_PROPE RTY);   126           St ring jaasC onf = Syst em.getProp erty(Const ants.JAAS_ CONF_PROPE RTY);
126           if  (jaasConf  == null)  {   127           if  (jaasConf  == null)  {
127                // Syste m property  not set,  use the To mcat defau lt   128                // Syste m property  not set,  use the To mcat defau lt
128                File jaa sConfFile  = new File (container .getCatali naBase(),   129                File jaa sConfFile  = new File (container .getCatali naBase(),
129                         Constants. DEFAULT_JA AS_CONF);   130                         Constants. DEFAULT_JA AS_CONF);
130                System.s etProperty (Constants .JAAS_CONF _PROPERTY,   131                System.s etProperty (Constants .JAAS_CONF _PROPERTY,
131                         jaasConfFi le.getAbso lutePath() );   132                         jaasConfFi le.getAbso lutePath() );
132           }   133           }
133       }   134       }
134     135  
135     136  
136       @Overr ide   137       @Overr ide
137         p ubli c
 boolean  a uthenticat e(Request  request, H ttpServlet Response r esponse)
  138         p rote c ted  boolean  doA uthenticat e(Request  request, H ttpServlet Response r esponse)
138                throws I OException  {   139                throws I OException  {
139     140  
140           if  (checkFor CachedAuth entication (request,  response,  true)) {   141           if  (checkFor CachedAuth entication (request,  response,  true)) {
141                return t rue;   142                return t rue;
142           }   143           }
143     144  
144           Me ssageBytes  authoriza tion =   145           Me ssageBytes  authoriza tion =
145                request. getCoyoteR equest().g etMimeHead ers()   146                request. getCoyoteR equest().g etMimeHead ers()
146                .getValu e("authori zation");   147                .getValu e("authori zation");
147     148  
148           if  (authoriz ation == n ull) {   149           if  (authoriz ation == n ull) {
149                if (log. isDebugEna bled()) {   150                if (log. isDebugEna bled()) {
150                    log. debug(sm.g etString(" authentica tor.noAuth Header"));   151                    log. debug(sm.g etString(" authentica tor.noAuth Header"));
151                }   152                }
152                response .setHeader ("WWW-Auth enticate",  "Negotiat e");   153                response .setHeader (AUTH_HEAD ER_NAME, A UTH_HEADER _VALUE_NEG OTIATE);
153                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);   154                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);
154                return f alse;   155                return f alse;
155           }   156           }
156     157  
157           au thorizatio n.toBytes( );   158           au thorizatio n.toBytes( );
158           By teChunk au thorizatio nBC = auth orization. getByteChu nk();   159           By teChunk au thorizatio nBC = auth orization. getByteChu nk();
159     160  
160           if  (!authori zationBC.s tartsWithI gnoreCase( "negotiate  ", 0)) {   161           if  (!authori zationBC.s tartsWithI gnoreCase( "negotiate  ", 0)) {
161                if (log. isDebugEna bled()) {   162                if (log. isDebugEna bled()) {
162                    log. debug(sm.g etString(   163                    log. debug(sm.g etString(
163                             "spneg oAuthentic ator.authH eaderNotNe go"));   164                             "spneg oAuthentic ator.authH eaderNotNe go"));
164                }   165                }
165                response .setHeader ("WWW-Auth enticate",  "Negotiat e");   166                response .setHeader (AUTH_HEAD ER_NAME, A UTH_HEADER _VALUE_NEG OTIATE);
166                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);   167                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);
167                return f alse;   168                return f alse;
168           }   169           }
169     170  
170           au thorizatio nBC.setOff set(author izationBC. getOffset( ) + 10);   171           au thorizatio nBC.setOff set(author izationBC. getOffset( ) + 10);
171     172  
172           by te[] decod ed = Base6 4.decodeBa se64(autho rizationBC .getBuffer (),   173           by te[] decod ed = Base6 4.decodeBa se64(autho rizationBC .getBuffer (),
173                    auth orizationB C.getOffse t(),   174                    auth orizationB C.getOffse t(),
174                    auth orizationB C.getLengt h());   175                    auth orizationB C.getLengt h());
175     176  
176           if  (getApply Java8u40Fi x()) {   177           if  (getApply Java8u40Fi x()) {
177                SpnegoTo kenFixer.f ix(decoded );   178                SpnegoTo kenFixer.f ix(decoded );
178           }   179           }
179     180  
180           if  (decoded. length ==  0) {   181           if  (decoded. length ==  0) {
181                if (log. isDebugEna bled()) {   182                if (log. isDebugEna bled()) {
182                    log. debug(sm.g etString(   183                    log. debug(sm.g etString(
183                             "spneg oAuthentic ator.authH eaderNoTok en"));   184                             "spneg oAuthentic ator.authH eaderNoTok en"));
184                }   185                }
185                response .setHeader ("WWW-Auth enticate",  "Negotiat e");   186                response .setHeader (AUTH_HEAD ER_NAME, A UTH_HEADER _VALUE_NEG OTIATE);
186                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);   187                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);
187                return f alse;   188                return f alse;
188           }   189           }
189     190  
190           Lo ginContext  lc = null ;   191           Lo ginContext  lc = null ;
191           GS SContext g ssContext  = null;   192           GS SContext g ssContext  = null;
192           by te[] outTo ken = null ;   193           by te[] outTo ken = null ;
193           Pr incipal pr incipal =  null;   194           Pr incipal pr incipal =  null;
194           tr y {   195           tr y {
195                try {   196                try {
196                    lc =  new Login Context(ge tLoginConf igName());   197                    lc =  new Login Context(ge tLoginConf igName());
197                    lc.l ogin();   198                    lc.l ogin();
198                } catch  (LoginExce ption e) {   199                } catch  (LoginExce ption e) {
199                    log. error(sm.g etString(" spnegoAuth enticator. serviceLog inFail"),   200                    log. error(sm.g etString(" spnegoAuth enticator. serviceLog inFail"),
200                             e);   201                             e);
201                    resp onse.sendE rror(   202                    resp onse.sendE rror(
202                             HttpSe rvletRespo nse.SC_INT ERNAL_SERV ER_ERROR);   203                             HttpSe rvletRespo nse.SC_INT ERNAL_SERV ER_ERROR);
203                    retu rn false;   204                    retu rn false;
204                }   205                }
205     206  
206                Subject  subject =  lc.getSubj ect();   207                Subject  subject =  lc.getSubj ect();
207     208  
208                // Assum e the GSSC ontext is  stateless   209                // Assum e the GSSC ontext is  stateless
209                // TODO:  Confirm t his assump tion   210                // TODO:  Confirm t his assump tion
210                final GS SManager m anager = G SSManager. getInstanc e();   211                final GS SManager m anager = G SSManager. getInstanc e();
211                // IBM J DK only un derstands  indefinite  lifetime   212                // IBM J DK only un derstands  indefinite  lifetime
212                final in t credenti alLifetime ;   213                final in t credenti alLifetime ;
213                if (JreV endor.IS_I BM_JVM) {   214                if (JreV endor.IS_I BM_JVM) {
214                    cred entialLife time = GSS Credential .INDEFINIT E_LIFETIME ;   215                    cred entialLife time = GSS Credential .INDEFINIT E_LIFETIME ;
215                } else {   216                } else {
216                    cred entialLife time = GSS Credential .DEFAULT_L IFETIME;   217                    cred entialLife time = GSS Credential .DEFAULT_L IFETIME;
217                }   218                }
218                final Pr ivilegedEx ceptionAct ion<GSSCre dential> a ction =   219                final Pr ivilegedEx ceptionAct ion<GSSCre dential> a ction =
219                    new  Privileged ExceptionA ction<GSSC redential> () {   220                    new  Privileged ExceptionA ction<GSSC redential> () {
220                         @Override   221                         @Override
221                         public GSS Credential  run() thr ows GSSExc eption {   222                         public GSS Credential  run() thr ows GSSExc eption {
222                             return  manager.c reateCrede ntial(null ,   223                             return  manager.c reateCrede ntial(null ,
223                                      credenti alLifetime ,   224                                      credenti alLifetime ,
224                                      new Oid( "1.3.6.1.5 .5.2"),   225                                      new Oid( "1.3.6.1.5 .5.2"),
225                                      GSSCrede ntial.ACCE PT_ONLY);   226                                      GSSCrede ntial.ACCE PT_ONLY);
226                         }   227                         }
227                    };   228                    };
228                gssConte xt = manag er.createC ontext(Sub ject.doAs( subject, a ction));   229                gssConte xt = manag er.createC ontext(Sub ject.doAs( subject, a ction));
229     230  
230                outToken  = Subject .doAs(lc.g etSubject( ), new Acc eptAction( gssContext , decoded) );   231                outToken  = Subject .doAs(lc.g etSubject( ), new Acc eptAction( gssContext , decoded) );
231     232  
232                if (outT oken == nu ll) {   233                if (outT oken == nu ll) {
233                    if ( log.isDebu gEnabled() ) {   234                    if ( log.isDebu gEnabled() ) {
234                         log.debug( sm.getStri ng(   235                         log.debug( sm.getStri ng(
235                                 "s pnegoAuthe nticator.t icketValid ateFail")) ;   236                                 "s pnegoAuthe nticator.t icketValid ateFail")) ;
236                    }   237                    }
237                    // S tart again   238                    // S tart again
238                    resp onse.setHe ader("WWW- Authentica te", "Nego tiate");   239                    resp onse.setHe ader(AUTH_ HEADER_NAM E, AUTH_HE ADER_VALUE _NEGOTIATE );
239                    resp onse.sendE rror(HttpS ervletResp onse.SC_UN AUTHORIZED );   240                    resp onse.sendE rror(HttpS ervletResp onse.SC_UN AUTHORIZED );
240                    retu rn false;   241                    retu rn false;
241                }   242                }
242     243  
243                principa l = Subjec t.doAs(sub ject, new  Authentica teAction(   244                principa l = Subjec t.doAs(sub ject, new  Authentica teAction(
244                         context.ge tRealm(),  gssContext , storeDel egatedCred ential));   245                         context.ge tRealm(),  gssContext , storeDel egatedCred ential));
245     246  
246           }  catch (GSS Exception  e) {   247           }  catch (GSS Exception  e) {
247                if (log. isDebugEna bled()) {   248                if (log. isDebugEna bled()) {
248                    log. debug(sm.g etString(" spnegoAuth enticator. ticketVali dateFail") , e);   249                    log. debug(sm.g etString(" spnegoAuth enticator. ticketVali dateFail") , e);
249                }   250                }
250                response .setHeader ("WWW-Auth enticate",  "Negotiat e");   251                response .setHeader (AUTH_HEAD ER_NAME, A UTH_HEADER _VALUE_NEG OTIATE);
251                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);   252                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);
252                return f alse;   253                return f alse;
253           }  catch (Pri vilegedAct ionExcepti on e) {   254           }  catch (Pri vilegedAct ionExcepti on e) {
254                Throwabl e cause =  e.getCause ();   255                Throwabl e cause =  e.getCause ();
255                if (caus e instance of GSSExce ption) {   256                if (caus e instance of GSSExce ption) {
256                    if ( log.isDebu gEnabled() ) {   257                    if ( log.isDebu gEnabled() ) {
257                         log.debug( sm.getStri ng("spnego Authentica tor.servic eLoginFail "), e);   258                         log.debug( sm.getStri ng("spnego Authentica tor.servic eLoginFail "), e);
258                    }   259                    }
259                } else {   260                } else {
260                    log. error(sm.g etString(" spnegoAuth enticator. serviceLog inFail"),  e);   261                    log. error(sm.g etString(" spnegoAuth enticator. serviceLog inFail"),  e);
261                }   262                }
262                response .setHeader ("WWW-Auth enticate",  "Negotiat e");   263                response .setHeader (AUTH_HEAD ER_NAME, A UTH_HEADER _VALUE_NEG OTIATE);
263                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);   264                response .sendError (HttpServl etResponse .SC_UNAUTH ORIZED);
264                return f alse;   265                return f alse;
265           }  finally {   266           }  finally {
266                if (gssC ontext !=  null) {   267                if (gssC ontext !=  null) {
267                    try  {   268                    try  {
268                         gssContext .dispose() ;   269                         gssContext .dispose() ;
269                    } ca tch (GSSEx ception e)  {   270                    } ca tch (GSSEx ception e)  {
270                         // Ignore   271                         // Ignore
271                    }   272                    }
272                }   273                }
273                if (lc ! = null) {   274                if (lc ! = null) {
274                    try  {   275                    try  {
275                         lc.logout( );   276                         lc.logout( );
276                    } ca tch (Login Exception  e) {   277                    } ca tch (Login Exception  e) {
277                         // Ignore   278                         // Ignore
278                    }   279                    }
279                }   280                }
280           }   281           }
281     282  
282           //  Send resp onse token  on succes s and fail ure   283           //  Send resp onse token  on succes s and fail ure
283           re sponse.set Header("WW W-Authenti cate", "Ne gotiate "   284           re sponse.set Header(AUT H_HEADER_N AME, AUTH_ HEADER_VAL UE_NEGOTIA TE + " "
284                    + Ba se64.encod eBase64Str ing(outTok en));   285                    + Ba se64.encod eBase64Str ing(outTok en));
285     286  
286           if  (principa l != null)  {   287           if  (principa l != null)  {
287                register (request,  response,  principal,  Constants .SPNEGO_ME THOD,   288                register (request,  response,  principal,  Constants .SPNEGO_ME THOD,
288                         principal. getName(),  null);   289                         principal. getName(),  null);
289     290  
290                Pattern  p = noKeep AliveUserA gents;   291                Pattern  p = noKeep AliveUserA gents;
291                if (p !=  null) {   292                if (p !=  null) {
292                    Mess ageBytes u a =   293                    Mess ageBytes u a =
293                             reques t.getCoyot eRequest() .getMimeHe aders().ge tValue(   294                             reques t.getCoyot eRequest() .getMimeHe aders().ge tValue(
294                                      "user-ag ent");   295                                      "user-ag ent");
295                    if ( ua != null  && p.matc her(ua.toS tring()).m atches())  {   296                    if ( ua != null  && p.matc her(ua.toS tring()).m atches())  {
296                         response.s etHeader(" Connection ", "close" );   297                         response.s etHeader(" Connection ", "close" );
297                    }   298                    }
298                }   299                }
299                return t rue;   300                return t rue;
300           }   301           }
301     302  
302           re sponse.sen dError(Htt pServletRe sponse.SC_ UNAUTHORIZ ED);   303           re sponse.sen dError(Htt pServletRe sponse.SC_ UNAUTHORIZ ED);
303           re turn false ;   304           re turn false ;
304       }   305       }
305     306  
306     307  
307       /**   308       /**
308        * Thi s class ge ts a gss c redential  via a priv ileged act ion.   309        * Thi s class ge ts a gss c redential  via a priv ileged act ion.
309        */   310        */
310         p r i vate  static cl ass Accept Action imp lements Pr ivilegedEx ceptionAct ion<byte[] > {   311         p ubl i c  static cl ass Accept Action imp lements Pr ivilegedEx ceptionAct ion<byte[] > {
311     312  
312           GS SContext g ssContext;   313           GS SContext g ssContext;
313     314  
314           by te[] decod ed;   315           by te[] decod ed;
315     316  
316            
AcceptActi on(GSSCont ext contex t, byte[]  decodedTok en) {
  317             public  AcceptActi on(GSSCont ext contex t, byte[]  decodedTok en) {
317                this.gss Context =  context;   318                this.gss Context =  context;
318                this.dec oded = dec odedToken;   319                this.dec oded = dec odedToken;
319           }   320           }
320     321  
321           @O verride   322           @O verride
322           pu blic byte[ ] run() th rows GSSEx ception {   323           pu blic byte[ ] run() th rows GSSEx ception {
323                return g ssContext. acceptSecC ontext(dec oded,   324                return g ssContext. acceptSecC ontext(dec oded,
324                         0, decoded .length);   325                         0, decoded .length);
325           }   326           }
326       }   327       }
327     328  
328     329  
329         p r i vate  static cl ass Authen ticateActi on impleme nts Privil egedAction <Principal > {   330         p ubl i c  static cl ass Authen ticateActi on impleme nts Privil egedAction <Principal > {
330     331  
331           pr ivate fina l Realm re alm;   332           pr ivate fina l Realm re alm;
332           pr ivate fina l GSSConte xt gssCont ext;   333           pr ivate fina l GSSConte xt gssCont ext;
333           pr ivate fina l boolean  storeDeleg atedCreden tial;   334           pr ivate fina l boolean  storeDeleg atedCreden tial;
334     335  
335           pu blic Authe nticateAct ion(Realm  realm, GSS Context gs sContext,   336           pu blic Authe nticateAct ion(Realm  realm, GSS Context gs sContext,
336                    bool ean storeD elegatedCr edential)  {   337                    bool ean storeD elegatedCr edential)  {
337                this.rea lm = realm ;   338                this.rea lm = realm ;
338                this.gss Context =  gssContext ;   339                this.gss Context =  gssContext ;
339                this.sto reDelegate dCredentia l = storeD elegatedCr edential;   340                this.sto reDelegate dCredentia l = storeD elegatedCr edential;
340           }   341           }
341     342  
342           @O verride   343           @O verride
343           pu blic Princ ipal run()  {   344           pu blic Princ ipal run()  {
344                return r ealm.authe nticate(gs sContext,  storeDeleg atedCreden tial);   345                return r ealm.authe nticate(gs sContext,  storeDeleg atedCreden tial);
345           }   346           }
346       }   347       }
347     348  
348     349  
349       /**   350       /**
350        * Thi s class im plements a  hack arou nd an inco mpatibilit y between  the   351        * Thi s class im plements a  hack arou nd an inco mpatibilit y between  the
351        * SPN EGO implem entation i n Windows  and the SP NEGO imple mentation  in Java 8   352        * SPN EGO implem entation i n Windows  and the SP NEGO imple mentation  in Java 8
352        * upd ate 40 onw ards. It w as introdu ced by the  change to  fix this  bug:   353        * upd ate 40 onw ards. It w as introdu ced by the  change to  fix this  bug:
353        * htt ps://bugs. openjdk.ja va.net/bro wse/JDK-80 48194   354        * htt ps://bugs. openjdk.ja va.net/bro wse/JDK-80 48194
354        * (no te: the ch ange appli ed is not  the one su ggested in  the bug r eport)   355        * (no te: the ch ange appli ed is not  the one su ggested in  the bug r eport)
355        * <p>   356        * <p>
356        * It  is not cle ar to me i f Windows,  Java or T omcat is a t fault he re. I   357        * It  is not cle ar to me i f Windows,  Java or T omcat is a t fault he re. I
357        * thi nk it is J ava but I  could be w rong.   358        * thi nk it is J ava but I  could be w rong.
358        * <p>   359        * <p>
359        * Thi s hack wor ks by re-o rdering th e list of  mechTypes  in the Neg TokenInit   360        * Thi s hack wor ks by re-o rdering th e list of  mechTypes  in the Neg TokenInit
360        * tok en.   361        * tok en.
361        */   362        */
362         p r i vate  static cl ass Spnego TokenFixer  {   363         p ubl i c  static cl ass Spnego TokenFixer  {
363     364  
364           pu blic stati c void fix (byte[] to ken) {   365           pu blic stati c void fix (byte[] to ken) {
365                SpnegoTo kenFixer f ixer = new  SpnegoTok enFixer(to ken);   366                SpnegoTo kenFixer f ixer = new  SpnegoTok enFixer(to ken);
366                fixer.fi x();   367                fixer.fi x();
367           }   368           }
368     369  
369     370  
370           pr ivate fina l byte[] t oken;   371           pr ivate fina l byte[] t oken;
371           pr ivate int  pos = 0;   372           pr ivate int  pos = 0;
372     373  
373     374  
374           pr ivate Spne goTokenFix er(byte[]  token) {   375           pr ivate Spne goTokenFix er(byte[]  token) {
375                this.tok en = token ;   376                this.tok en = token ;
376           }   377           }
377     378  
378     379  
379           //  Fixes the  token in- place   380           //  Fixes the  token in- place
380           pr ivate void  fix() {   381           pr ivate void  fix() {
381                /*   382                /*
382                 * Usefu l referenc es:   383                 * Usefu l referenc es:
383                 * http: //tools.ie tf.org/htm l/rfc4121# page-5   384                 * http: //tools.ie tf.org/htm l/rfc4121# page-5
384                 * http: //tools.ie tf.org/htm l/rfc2743# page-81   385                 * http: //tools.ie tf.org/htm l/rfc2743# page-81
385                 * https ://msdn.mi crosoft.co m/en-us/li brary/ms99 5330.aspx   386                 * https ://msdn.mi crosoft.co m/en-us/li brary/ms99 5330.aspx
386                 */   387                 */
387     388  
388                // Scan  until we f ind the me ch types l ist. If we  find anyt hing   389                // Scan  until we f ind the me ch types l ist. If we  find anyt hing
389                // unexp ected, abo rt the fix  process.   390                // unexp ected, abo rt the fix  process.
390                if (!tag (0x60)) re turn;   391                if (!tag (0x60)) re turn;
391                if (!len gth()) ret urn;   392                if (!len gth()) ret urn;
392                if (!oid ("1.3.6.1. 5.5.2")) r eturn;   393                if (!oid ("1.3.6.1. 5.5.2")) r eturn;
393                if (!tag (0xa0)) re turn;   394                if (!tag (0xa0)) re turn;
394                if (!len gth()) ret urn;   395                if (!len gth()) ret urn;
395                if (!tag (0x30)) re turn;   396                if (!tag (0x30)) re turn;
396                if (!len gth()) ret urn;   397                if (!len gth()) ret urn;
397                if (!tag (0xa0)) re turn;   398                if (!tag (0xa0)) re turn;
398                lengthAs Int();   399                lengthAs Int();
399                if (!tag (0x30)) re turn;   400                if (!tag (0x30)) re turn;
400                // Now a t the star t of the m echType li st.   401                // Now a t the star t of the m echType li st.
401                // Read  the mechTy pes into a n ordered  set   402                // Read  the mechTy pes into a n ordered  set
402                int mech TypesLen =  lengthAsI nt();   403                int mech TypesLen =  lengthAsI nt();
403                int mech TypesStart  = pos;   404                int mech TypesStart  = pos;
404                LinkedHa shMap<Stri ng, int[]>  mechTypeE ntries = n ew LinkedH ashMap<>() ;   405                LinkedHa shMap<Stri ng, int[]>  mechTypeE ntries = n ew LinkedH ashMap<>() ;
405                while (p os < mechT ypesStart  + mechType sLen) {   406                while (p os < mechT ypesStart  + mechType sLen) {
406                    int[ ] value =  new int[2] ;   407                    int[ ] value =  new int[2] ;
407                    valu e[0] = pos ;   408                    valu e[0] = pos ;
408                    Stri ng key = o idAsString ();   409                    Stri ng key = o idAsString ();
409                    valu e[1] = pos  - value[0 ];   410                    valu e[1] = pos  - value[0 ];
410                    mech TypeEntrie s.put(key,  value);   411                    mech TypeEntrie s.put(key,  value);
411                }   412                }
412                // Now c onstruct t he re-orde red mechTy pe list   413                // Now c onstruct t he re-orde red mechTy pe list
413                byte[] r eplacement  = new byt e[mechType sLen];   414                byte[] r eplacement  = new byt e[mechType sLen];
414                int repl acementPos  = 0;   415                int repl acementPos  = 0;
415     416  
416                int[] fi rst = mech TypeEntrie s.remove(" 1.2.840.11 3554.1.2.2 ");   417                int[] fi rst = mech TypeEntrie s.remove(" 1.2.840.11 3554.1.2.2 ");
417                if (firs t != null)  {   418                if (firs t != null)  {
418                    Syst em.arrayco py(token,  first[0],  replacemen t, replace mentPos, f irst[1]);   419                    Syst em.arrayco py(token,  first[0],  replacemen t, replace mentPos, f irst[1]);
419                    repl acementPos  += first[ 1];   420                    repl acementPos  += first[ 1];
420                }   421                }
421                for (int [] markers  : mechTyp eEntries.v alues()) {   422                for (int [] markers  : mechTyp eEntries.v alues()) {
422                    Syst em.arrayco py(token,  markers[0] , replacem ent, repla cementPos,  markers[1 ]);   423                    Syst em.arrayco py(token,  markers[0] , replacem ent, repla cementPos,  markers[1 ]);
423                    repl acementPos  += marker s[1];   424                    repl acementPos  += marker s[1];
424                }   425                }
425     426  
426                // Final ly, replac e the orig inal mechT ype list w ith the re -ordered   427                // Final ly, replac e the orig inal mechT ype list w ith the re -ordered
427                // one.   428                // one.
428                System.a rraycopy(r eplacement , 0, token , mechType sStart, me chTypesLen );   429                System.a rraycopy(r eplacement , 0, token , mechType sStart, me chTypesLen );
429           }   430           }
430     431  
431     432  
432           pr ivate bool ean tag(in t expected ) {   433           pr ivate bool ean tag(in t expected ) {
433                return ( token[pos+ +] & 0xFF)  == expect ed;   434                return ( token[pos+ +] & 0xFF)  == expect ed;
434           }   435           }
435     436  
436     437  
437           pr ivate bool ean length () {   438           pr ivate bool ean length () {
438                // No ne ed to reta in the len gth - just  need to c onsume it  and make   439                // No ne ed to reta in the len gth - just  need to c onsume it  and make
439                // sure  it is vali d.   440                // sure  it is vali d.
440                int len  = lengthAs Int();   441                int len  = lengthAs Int();
441                return p os + len = = token.le ngth;   442                return p os + len = = token.le ngth;
442           }   443           }
443     444  
444     445  
445           pr ivate int  lengthAsIn t() {   446           pr ivate int  lengthAsIn t() {
446                int len  = token[po s++] & 0xF F;   447                int len  = token[po s++] & 0xF F;
447                if (len  > 127) {   448                if (len  > 127) {
448                    int  bytes = le n - 128;   449                    int  bytes = le n - 128;
449                    len  = 0;   450                    len  = 0;
450                    for  (int i = 0 ; i < byte s; i++) {   451                    for  (int i = 0 ; i < byte s; i++) {
451                         len = len  << 8;   452                         len = len  << 8;
452                         len = len  + (token[p os++] & 0x ff);   453                         len = len  + (token[p os++] & 0x ff);
453                    }   454                    }
454                }   455                }
455                return l en;   456                return l en;
456           }   457           }
457     458  
458     459  
459           pr ivate bool ean oid(St ring expec ted) {   460           pr ivate bool ean oid(St ring expec ted) {
460                return e xpected.eq uals(oidAs String());   461                return e xpected.eq uals(oidAs String());
461           }   462           }
462     463  
463     464  
464           pr ivate Stri ng oidAsSt ring() {   465           pr ivate Stri ng oidAsSt ring() {
465                if (!tag (0x06)) re turn null;   466                if (!tag (0x06)) re turn null;
466                StringBu ilder resu lt = new S tringBuild er();   467                StringBu ilder resu lt = new S tringBuild er();
467                int len  = lengthAs Int();   468                int len  = lengthAs Int();
468                // First  byte is s pecial cas e   469                // First  byte is s pecial cas e
469                int v =  token[pos+ +] & 0xFF;   470                int v =  token[pos+ +] & 0xFF;
470                int c2 =  v % 40;   471                int c2 =  v % 40;
471                int c1 =  (v - c2)  / 40;   472                int c1 =  (v - c2)  / 40;
472                result.a ppend(c1);   473                result.a ppend(c1);
473                result.a ppend('.') ;   474                result.a ppend('.') ;
474                result.a ppend(c2);   475                result.a ppend(c2);
475                int c =  0;   476                int c =  0;
476                boolean  write = fa lse;   477                boolean  write = fa lse;
477                for (int  i = 1; i  < len; i++ ) {   478                for (int  i = 1; i  < len; i++ ) {
478                    int  b = token[ pos++] & 0 xFF;   479                    int  b = token[ pos++] & 0 xFF;
479                    if ( b > 127) {   480                    if ( b > 127) {
480                         b -= 128;   481                         b -= 128;
481                    } el se {   482                    } el se {
482                         write = tr ue;   483                         write = tr ue;
483                    }   484                    }
484                    c =  c << 7;   485                    c =  c << 7;
485                    c +=  b;   486                    c +=  b;
486                    if ( write) {   487                    if ( write) {
487                         result.app end('.');   488                         result.app end('.');
488                         result.app end(c);   489                         result.app end(c);
489                         c = 0;   490                         c = 0;
490                         write = fa lse;   491                         write = fa lse;
491                    }   492                    }
492                }   493                }
493                return r esult.toSt ring();   494                return r esult.toSt ring();
494           }   495           }
495       }   496       }
496   }   497   }