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.
# | 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 |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 14 | 968 |
Changed | 12 | 24 |
Inserted | 1 | 1 |
Removed | 0 | 0 |
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 |
No regular expressions were active.
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
|
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 |
|
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 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993–2017 Araxis Ltd (www.araxis.com). All rights reserved.