From 86fc328325b260ff3bb2a58f9e15de8f8986a73a Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Thu, 27 Jun 2019 16:04:52 -0700 Subject: [PATCH] Intel AMT activation improvements. --- agents/MeshCmd-signed.exe | Bin 5783448 -> 5783232 bytes agents/MeshCmd64-signed.exe | Bin 5366168 -> 5365952 bytes agents/meshcmd.js | 248 ++++++++++++++++++------------------ agents/meshcmd.min.js | 248 ++++++++++++++++++------------------ webserver.js | 101 +++++++-------- 5 files changed, 301 insertions(+), 296 deletions(-) diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 4835db60955ffed4030b3d8416e864ab4eb9f6c7..8523f986c8ba4d4fc3752aeb54112ba78d99fd37 100644 GIT binary patch delta 3647 zcmdUxc~nzZ9>)o52njm~BKkmq1OWq@r`{L=gA_&FM;MFMkURvkumk#Hme8Hx-;B*q#JJxax!u8Wo@2t`tAIozL52N=Us=|;}X^h~905u*I`e9%gL?_dI zfUBa%Lv<>xg!V*QT5xGDjSNRdAR~>J=91@wATFQy8r^o0n+{%C>4vn{10)32zm_-%6b1vM$uNY4g$0SE;JlGg#+(CWjup&{qJy`rkn&SBOeU)- zOsUfv^g4BdPQ_3%O3!32R2#ZC;(k!eaaSjEWFJ^kL%TqEPD@ zg=z_yhGG)yVbcF= zg>Zf@?G8&%5{Y9-k6}=GlC1kxn{nhR63YSDOfJIRFNh25-$LAB-hGL{Sbm0FwuD2~ zi36bU3gNmb6`2gisMK_*Wr7HB#?xM6+{0;RyWl=&=(H+EMVStiJ;<)mwCpM1*GvX> z#nPToB&Dt4-ZtU@@6HhwyqG|9yV^88Umf6HHA(K)7ImIvKxHhB`0+gH2UT1tH-NQo zDwV}h3Oz%mYuQ7iG`L$Kl#1z89M)~=3^~np?soQ+Oh$!6&K2STQS8j+Hc~rS+nmS; zKlC67_Yha0CeVDd$QOHv9Y+R}k0$mrx9Vz0pCES4538Yj(sXK7x^^xVE=G6bVyaBm zyRaY^HyI~$gq4el4b+xk5J5)b1kX!|Bg`(vMXO5_?O|dG;X$~8b_0QLk|Uh2Cmw-H z4bB^_)I@iBMl088GSm#ZmCbT=tQdb?OYmX#Uef=AM!y~!S?4l(J!V@FHJD;kXJIBx z@y7+9J(TdEf-7}~j5CQoK*iEF5XDJyHf^?P&aLsZU9ZxuYe-+u-W8f=fF=M4j3B ze`ltVzipuhmq`HlZzn?rWH9XfjZ>AFCo+2dsFovnWlT~HPJtpfLERqU%g0B13RK?Ag1$$R?Gr3d%Q|4nyoTQ{Zd`x!6w8TE$69H4Z zqt`D(X-8qVduCa;5#4uz9l?VGHDt7{Su-gAM2-y)F;&G((&K6fp_B{tdPZwt?-xS# za&3WEJrVk*F4USM==Gd9YcPoFHo}L}^`tM{$)kBjyj13K;Q0l@v%*}3$PHw;aZ@R= z;&9~fq7FCJsg`&ctINm^b1!pq5G0h~&Cs}m*g2M=)J-S&38Ti zvBBUYYses&wFOfg1$e`j8Z5hiEG1*0rG`k@Cs%fMTR3nL>ugpK*5hq#+nNhxB2>MQ zn1+po#xkt`Giu2IR+K%Qo<-Y3aV<%KS;ukMrzx~6_}1YXRXfRexK>X3z=k?3xyyf$ z*g;e|mUdj60-K9Cb7xe;Sp|G(FD1cHbdgwheK3V<66DB+>k4NoFmTy2nroET6HiO1 zxPmL)y+pj+LOSZTtY_)&58E%1e3j=B1J|a zGGsIoi9{jM$QVS9#2{mlSmYxl4jG4xN8*tQNCGkunS@M6rXW+1X~=ZscgPH*`gY>_ z1dbQ93zKrh^2YprD!E7GaNFdclE!m>4vT&CXdTbOqqgGdJnrS|uUGYz2A=w?p!m(% zH0x_=Q%a5dL`ecyaqH2S1Fly06HL1~7QTD>kC%n6{JJsfsb?#{7NynS4!CRQw0vK{ zS4kd||He&95u9#<$I_%#*~dri+9w%3u);V0*v$x^{42x#Mo9x&ZQADC8k}EfRm`PM zrtRLQ`s{{}Z)M@Sv~bAnyL_HvwmBuk#llJ~Y95Mg8?_ck`O|=~teVF#^Brik+qH z2VEC`IpSJy#WSn=(6)IGUhNy0_h%=$e_mEuWPQ%9i}^u&%C6O{IpMkb7qNRw=&)Ty zTbk~C|N4&2M`he`2_yGru6Pxd>g1kfm)=;xi~oIdN^Y=gLv{QcVd17zmj37XPbmAO zX)o&@6d%`JSaLpiynEu`zrUP$BsqTQcR`j%gCSj(^ej7Ks5l}bVy1YYt$pz7xYca} zj=gobr?vYR`Rev)r&eD5tEA1{;ar=3|D>-^*>6xU zyYlu}_62{z<}YVfl_cyQ-9m>oRTaLoYxM{?$ZrwFt(Y8sY-HBQ-}r9VZ2aljsJL_T z!iJ_9t#2(Y1CrkEJ<%{fCu@6(!ntB+*=Seq+=el&bIV7S-?-JzdDkc6QC8o8;G!fK z;r*iKE#9YB8h$irPi=bgdE2wHL-)z!)xK2r@mD8b&WUMGUbWWq+lTSi&2G^}8PP58 zTTa*J&<%bEo4jwS6#qQ6v2~qcdck9V*OpIjYIrp-UdBy3`&?$dY3queG52iOG@iDw Gu=p3vN|9y& delta 2530 zcmcK4dsGu=765Pt5kerK2nZI!C<*~FMBGHVfC`}kQ9u-or3wTH8a2RyfK)^T6wxOlf&OGvAQswylRL>|yi_$v9#}#uH;=LU_cK@QE2QCjw$Y zEXf2ikyw#Q#G2R;TQZs05qmO)yh9v_BM}lO!jh?E8gVAm$qeE`T#1Od5qC0^c#v5{ zOgxE%%qCuB4*3I-ay^X9H_>FdIxSP3Cg+$W*$bwyL?a_}$vooCm1yADbR2pH#_07C z*n6=XHM+HI`sh8ZDnX~oROvJ+$$U>wK0hfVnF1-vV{!GX2cvN*xG)0lWhJCCxVIWC zF}Df^u(=xSF#J>CV}CV-aU(S#WYAF|<6-Gum?#jZ>r^^5JJrvRmAK)lOEA?*lgy^3 zsb{68rDST-X&g=R8g?`b*lFxc7Rv%<*7!0&Hr{mX=Hn~{;LUQRx5Fe9egShaUL~`|oMsTBO$&%Irw7bXb_672M^jGGsi=>V@d%B>e# zk3;0>!!zGpggN?hu&e@XknI2&KJNr`Q&$f*O|9CX1&rPa-qs#$MusL4Sgm?=*~R)Z zywCvw7<>|(?cct3ObG;VXHSBT!DA($z(WNxJ8bWSFudIb)mYyPGr5*-sG z6j<(TCB%;7&ewp?|Eak+YOW?@9IA(fC~SZt?q~xnVhlY!@kJvD-GAK^qJ#|^b+Rr@ zrB!>d3FFlo@``zU^pN1MwBuXH$lZ{cW~4lU;TF{sNUWQNzIUmi(6=a z{YOtwZ2j1U!4^>Ko4^S#wNXPtD>xu`i276RFPo&_j1K618f-Dk)*eI*?F!D1{H*AC+`t_%eFTX|T! znf_AqWfmx@qgYTcgkWpC^0#qp@nkQ|z^$7oFK(8L5x#5#Qyl394-BuSVSkIUeN@no zfim;4l-yImzL9dck2>t`DVifq%@n^oMqhx}wTSTJ6Ex)S$`I(A(0#O)*B9TcWi&>$ z2=SL{r4>%#`8Z-_1+B&CHlbxOXIybr2OQCF0udL|5B7#0iR$=_H6mC4#KbUlmQGHu zJ0w}YRz+Vh{m#iq2iBFoSYyZ7y^l6s)ib34JIiUp=g&e4p56ym`j{!I1|SA&UntGF z!2vjEi68$A4uuuNKzxWV@gwue0(of#hAXhy;;f5<(PYF#eCoqJN!s-d5*@m77(u+CNyQaR^dW?y#GRmc0= zcQ}HDKqj!z?$0Rhu8sRS>FKvO;?Tlp<+fbQSmhGMv;`fvwD}Rn{y9+$Q{K8eZdt{k zZ-I5yr@YT|{fo}tJb7Vg+cyK}*s%Kk*sRJ0!XJkCskYwBoFm(}WL%LR-WNN(*ly8n zPmAoX4}3p+ROxqX>#q6i$RoeX4;f9!kiDq(pPN>Qot|F*zUGB|!-L+N_+Y8`<1YudvHTz}izdUH1z6_0@_w#FI(x2E8ZB`)Hgzuu zE_fnfOpRvS8d+PEe=V7JrkU>$qGS%W#RLzm+)^VE{F=lt;|+}R8H3!bMs^RBKYBX^ zbsLo1ul^xsBs{39p}VU%ex&G~2)|Ni>C+{*lIzfTS$>VJoqUg3dFG!z@9w|+r;UG; z7cFQs$z74sY-ZxZi+CRv)n7?ZcYN=1Xw0dwl7YOYpYENx-Fbc%r`vPpgMh zzvmUPw$akbH`vLiIkMwi9q)Rc@DNl=cl5`N$p3oBQMA(_d&RTG%|TX=ja{-sdsW-v zXhX>NJGI5ji;jOCIYU+9`u61a5Xxw@lA+PXut?PZ^@SGhD^ z;TM_|J~vv^6Fu_$nPZNV&5KP9n?I7dwQ2Jc;?#k<8_UC2TUlH43PsZA4i6*N7#JA* E8~WNBV*mgE diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index 5edfd3a74544856fc876f5fa259d9e95f59149e6..5c5f1c223380fb5721336577e45259cf1c88718b 100644 GIT binary patch delta 3656 zcmdUxc~nzZ9>)oWm;}PUNklKoZsa|}1u8K@0CxdXk-9@n9^1)+A-G#bMyPA8cKiv} ztvXuwy*X|bMvn`Q)@ju`o#Ji}I*NK6m+4fUUlPFJp=VD2nlm})bI!|s_uk)fzrWvo zt52SBt#3Hvx_3Iyb=AU^GkMvrY-3d;ucnb_!xia*@DVpefOJKKhzJoQ?uZ8>K|B#J z#2fKJd=Wpy9|=GLksu@(>4t#(jDkCd8MnUGlEeRW8jTf?)c;iaSwWg_@IVy(C5|h>+!;qmy3#TWl ztXxvgnejc*wN9KNBlt#7EX7>gEBm8GW8sLY@ZG{VP`zP-Kqz2`LA{XG!mEEVike0d zi^L;xB*EG!qL0I2NE8jV`eo3|?!nVaEX8dbN29~UWF{FISut=Th6b+6p)y#!nsJwC zEEdjCW{Hc7i;7WzH$#cFGKUs)fzsPdEPVVW^_Xnn%56@?X-!6p*`&`h={TY!X0E(K zZ*d;PgpfIy7L3|yY6@X-cD6~SwUkW7ZFDjcj|1q6jL7i;T@!=hE|X{#j-viN$bQ4P zC*oX_k%TEpl*V9b%NV9MGLl4h>W-4gV?dQlr9K+HnbYWI5RJoLi3xgqf$6&?rwklV zpcAZpN7HnH-&Bp6X!Ls1G)`v=s2n|kC5d!UfZhN1J%k1k>kl)>(?m~Mhh?y5JYDqO zn6=*oI*135L{GzYCG~+F$(^-G%YQIJ1a@t&E`96sGeezURPo)BJnKB8;$A8ZQ_L~;h1FH%oFB?P&YWGz#yW=QZIO{ zpq`MQibm^G)gs7NP%*>@vVI^rq4tD^QW_AcHQ>G~twGhM8DoaYP^RZlt+p~p#j^No zH{k*KLurq9K8AJh(WYF^Y{qhnB7KOhbSlb0eTwmeM++D+?A%VhfiyF2uznKS$1{>Z z+9tKPJ>!mz3wB8P(4e3_-w%MVqalHv``PN8^S(mZ6^XVyLaC_T7Qa<;+TS5LTXg?b za;@@8D@0>?3MzMmWB(hYq7qoApuO$#>f1q7ZPogJC$4_KEvefE8UelfQ>JGbXD&3E z4H?eL`di zmj+;uzLAbk--h8?)uz))ecD~|KG)5SI;vOKEsN^erQTm4$RN zOdNyDX7gEJ2rWVzdsTE8Tui4yu%rlE@|=ZCS4d08){naoa4W{0+oDRgdEf!BQfVwK zFQ)wV7xr-N4td(b^@U^E7`QT&6KfXVCEs}Y29p~JH5bMN2N9TITT4ml8|KN1Ee34f+&#wh!Poqq#|jE3Q0#YkW6GC zG6)%r3_*q>!;s;~2qX*1MskpmR{b3H;w)Y;ylPZevJ0-vd%fnOU{TrbqaItMiU}RD zJ};1{pSdTksuM=;db(;?pKCKJ#3_F++Wy>w&FE|0c3v&}!8*7##{fH>s=UE-(Lk)fCMm>KqaXxIf| z%F;Ebk|HnnhzOm1diaO=^Y7-%Ry^>Xx%9yIo)^ci+heUr(kwhs*N}MYwr|$u@Jh9O zef^r=55)P;Ya-U&I2Q10Qe@cax!cI|njm%maT_N+>OSSdD)Wh^n3Y4%$t#ABXo=tP z&##Uz-$~_ujM6MPlbQ1Qf#59Hty}apufII`m$f0MH(Iw=NIo@ z`-tx^xsm6kJ9tf6uw)#2wyFPTO&ZIc=5x|+MfJhe;)<}pB{S^MH!e>y3+i8I)){Z9 zm(PEesmRjK_RKjW(GK~#GUMr=>guQD9QjA)iWL5xX+b}XXqjAj;Jd2GhV(17SLTj* d`=av4JoCfNA~yU}ZPVF%{&SBAlU!U}{sS|7Uw8lj delta 2506 zcmcK5c~nzp765QwK=z=rDT?qEk+3B}F32iNaA6Gr9T-JONCHFwF(jxcM#ZJeu?nKs zRz~#Lj;+%wi14h-NXJ$*7I$guQIXNQTk+6Q4l;FaKwH~6&VQ40emU>mci;QI`{jNw zZC|zXww-9_H7;Rzvo39}WYT!nXR3|NdLv`PBj&_{3?r7ridYjHVoU6ZJ>e4vGMtPc zBZ(t%BF@BxxROz1G;t$i$XMb|#t{$VNmw$TOdwulBJn1Zhz}7EU*bpnNdO5XLL%af zj2JAfGS%7&wN}D0*5UzX{RTTR2_ln8Ft@=D4o$@K^LI8+z~nB%iE%1HbXaO>a^ID2IFymJQT%HrdF3yQZ5*r_3PP5Ql~BPjpW<1 z^r)0+lQi(f$2s7H9#WWs z`Q~C*tV#zDbdiA&t5jfzp;;gvIvS&-Q$ZmmV-}5L{bz{6nR8**;KM84T!dg#Iam`4 zF39FWD87(`y^T)*t5qwCOCoTN5W<}USiN4OieO9BgUc>7o#DA$h{u_E;N|xAwPQpO z&z;T#9fOBNkc7IfH37JA`C_#k44h=l|~a$8Lkj#hDe*RbN)2)2U0!bV8xf$2SuBLBMjSqae?mI~xm;|EK2S zsJZr9;`u~~MUNzSk84eW=?qUK!hvM)@cVU72$aPdb*U~*QKAlDm1?c7+?QR(RzLDBj))1?ix|WEt(RKlB8}77ShJkb&CN1fF;? zlNvH21Kg3DP5mjkC2}%tMt2NXgDd7{gFQCRf>9_hqUY(=)Slz!QLJaG%o+u`)M!RE zgl^S<1-8uvYg60`)4k{|;jRIPp_n`ehM_zd_@-N}ai<4;l}!{opm-X^W)wgoHs;8F z8^;xo6@WLcbf-M|-^Nm98EDBR1`xl?%W}>=Q@hv^WnH@JGif}TMi_Igpw&F zjD(X25=o*+G?_|bNGypX@kBxr$TTvY%pfyKB1t02B!#4sG$JMGT-|cn`>9M1vPRh| zF~6t3XL8%k`z;-d3$Kei+#FEyRv-#*|$>B@A$6S?fJc( zw@aJR;kvBaz%@A~@e z!qU#O%a29cTgBbladE1?qK@Zz$|d%Cl03YrEzJ4Y@$Rl)mKwfUEEwVUMQ>90u1VUX z(wgtp)3b%|W@dblv+1e*-Or+b+#*Qnxz*V5$+M{Mmpb3r{zGkGXmGTZ_!`7Dc1(rtdhtE!~$WWX&=sTBRy*BpH`}>zw z?C$pdSJ37OiJFMK%8suad25bi%?;UOgE%B;N=Voov6rQd-@2LWp7R+Siy&7E=dQpf ztJZG(=38lM`-U~C`kQC2TsrQTW%7%D*rU-!@@bZIaMz z?-uirj9H6h5sQip3)Xg;{}R)GRAgJ}eeX}bE0oubS*L{l`J*Ee=4-XpZ3bz>=~&11 zZA>R9zuUdjS+8wqHS1oqzINYPPyOnvOzhE5qrm@JU!9>%_{rCc^B)~t5u#jmie0x_ zmEpT9d8hZKFBdJ7I>lW*z$>^QU)grgz2hCd tVGR>bifxY6MJHUVn-=?g;K9y>6ZP6=kBhPoYa6Z&7`GhIjWjbe`wz9T=&%3) diff --git a/agents/meshcmd.js b/agents/meshcmd.js index 4a3d3e49..d105e332 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -517,13 +517,18 @@ function run(argv) { settings.protocol = 'http:'; settings.localport = 16992; debug(1, "Settings: " + JSON.stringify(settings)); - if (settings.password != null) { activeToCCM(); } else { activeServerCCM(); } + if (settings.password != null) { activeToCCM(); } else { activeToACM(); } } else if (settings.action == 'amtacm') { // Start activation to ACM if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; } if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; } debug(1, "Settings: " + JSON.stringify(settings)); activeToACM(); + } else if (settings.action == 'amtdiscover') { + // Intel AMT server discovery, tell the server the state of Intel AMT. + if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; } + debug(1, "Settings: " + JSON.stringify(settings)); + activeToACM(); } else if (settings.action == 'amtdeactivate') { // Deactivate CCM debug(1, "Settings: " + JSON.stringify(settings)); @@ -823,91 +828,6 @@ function activeToCCMEx3(stack, name, responses, status) { } -// -// Activate Intel AMT to CCM with server activation -// - -function activeServerCCM() { - settings.noconsole = true; - mestate = {}; - var amtMeiModule, amtMei; - try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } - amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); - amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); - amtMei.getVersion(function (val) { mestate.vers = {}; if (val != null) { for (var version in val.Versions) { mestate.vers[val.Versions[version].Description] = val.Versions[version].Version; } } }); - amtMei.getUuid(function (result) { - if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } - if ((mestate.vers == null) || (mestate.vers['AMT'] == null)) { console.log("Unable to get Intel AMT version."); exit(100); return; } - if (mestate.ProvisioningState == null) { console.log("Unable to read Intel AMT activation state."); exit(100); return; } - if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } - if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } - startLms(activeServerCCMEx); - }); -} - -function activeServerCCMEx(state) { - osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeServerCCMEx2); -} - -function activeServerCCMEx2(stack, name, responses, status) { - if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); } - else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); } - - // Establish WebSocket connection to activation server - var options = http.parseUri(settings.url); - options.checkServerIdentity = onVerifyServer; - options.rejectUnauthorized = false; - var connection = http.request(options); - connection.on('upgrade', function (response, socket) { - console.log('Connected, requesting activation...'); - settings.xxsocket = socket; - socket.on('end', function () { console.log('Connection closed'); exit(0); }); - socket.on('error', function () { console.log('Connection error'); exit(100); }); - socket.on('data', function (data) { - // Parse and check the response - var cmd = null; - try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } - if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } - if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } - if (cmd.action != 'ccmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } - if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } - settings.xxprofileScript = cmd.profileScript; - settings.xxrawpassword = cmd.rawpassword; - - // We are ready to go, perform CCM activation. - osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, activeServerCCMEx3); - }); - socket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate', realm: responses['AMT_GeneralSettings'].response['DigestRealm'], uuid: mestate.uuid, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'] }); - }); - connection.end(); -} - -function activeServerCCMEx3(stack, name, responses, status) { - if (status != 200) { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); - console.log('Failed to activate, status ' + status); - } else if (responses.Body.ReturnValue != 0) { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); - console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); - } else { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-success', uuid: mestate.uuid }); - if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) { - console.log("Intel AMT ACM activation success, applying profile..."); - settings.scriptjson = settings.xxprofileScript; - settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password - settings.username = 'admin'; - startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); - return; - } else { - console.log('Success'); - settings.xxsocket.end(); - exit(0); - return; - } - } - settings.xxsocket.end(); - exit(1); -} // @@ -976,11 +896,11 @@ function getTrustedHashes(amtMei, func, tag) { } // -// Activate Intel AMT to ACM +// Activate Intel AMT to with server (ACM or CCM) // function activeToACM() { - console.log('Starting Intel AMT provisioning to Admin Control Mode (ACM) attempt...'); + console.log('Starting Intel AMT activation attempt...'); settings.noconsole = true; // Display Intel AMT version and activation state @@ -992,10 +912,11 @@ function activeToACM() { amtMei.getVersion(function (val) { mestate.vers = {}; if (val != null) { for (var version in val.Versions) { mestate.vers[val.Versions[version].Description] = val.Versions[version].Version; } } }); amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getControlMode(function (result) { if (result != null) { mestate.controlMode = result.controlMode; } }); // controlMode: 0 = NoActivated, 1 = CCM, 2 = ACM amtMei.getDnsSuffix(function (result) { if ((mestate.vers == null) || (mestate.vers['AMT'] == null)) { console.log("Unable to get Intel AMT version."); exit(100); return; } if (mestate.ProvisioningState == null) { console.log("Unable to read Intel AMT activation state."); exit(100); return; } - if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } + if ((settings.action != 'amtdiscover') && (mestate.controlMode == 2)) { console.log("Intel AMT already activation in admin control mode."); exit(100); return; } if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } var fqdn = null; if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } @@ -1025,12 +946,13 @@ function getFwNonce() { if (status != 200) { console.log("Unable to get firmware activation nonce, status=" + status); exit(100); return; } var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce']; var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm']; - activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid); + var allowedModes = responses['IPS_HostBasedSetupService'].response['AllowedControlModes']; // 1 = CCM, 2 = ACM + activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid, allowedModes); }); } // Connect to the activation server and perform ACM activation -function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { +function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid, allowedModes) { console.log('FQDN: ' + dnsSuffix); console.log('UUID: ' + uuid); console.log('Realm: ' + digestRealm); @@ -1039,11 +961,11 @@ function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { // Establish WebSocket connection to activation server var options = http.parseUri(settings.url); - //options.checkServerIdentity = function (clientName, certs) { }; // TODO options.checkServerIdentity = onVerifyServer; options.rejectUnauthorized = false; var connection = http.request(options); connection.on('upgrade', function (response, socket) { + settings.xxsocket = socket; console.log('Connected, requesting activation...'); socket.on('end', function () { console.log('Connection closed'); exit(0); }); socket.on('error', function () { console.log('Connection error'); exit(100); }); @@ -1053,52 +975,135 @@ function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } - if (cmd.action != 'acmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } - if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } - if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } - if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } - if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } + switch (cmd.action) { + case 'acmactivate': { + // Server responded with ACM activation response + if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } + if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } - // We are ready to go, perform activation. - cmd.index = 0; - performAcmActivation(cmd, function (result) { - if (result == false) { - console.log('Intel AMT ACM activation failed.'); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-failed', uuid: mestate.uuid }); - socket.end(); - exit(1); - } else { - if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { - console.log('Intel AMT ACM activation success, applying profile...'); - settings.scriptjson = cmd.profileScript; - settings.password = cmd.rawpassword; // This is only going to work if the server sends the raw password - settings.username = 'admin'; - startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); + cmd.index = 0; + // If we are in CCM mode, deactivate. + if (mestate.controlMode == 1) { + amtMei.unprovision(1, function (status) { + if (status == 0) { + console.log('Intel AMT CCM deactivated, holding 10 seconds...'); + // We are ready to go, perform ACM activation. + settings.xxTimer = setTimeout(function () { performAcmActivation(cmd, AcmActivationCompleted); }, 10000); + } else { + console.log('Intel AMT CCM deactivation error ' + status); exit(1); return; + } + }); } else { - console.log('Intel AMT ACM activation success.'); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-success', uuid: mestate.uuid }); - socket.end(); - exit(0); + // We are ready to go, perform ACM activation. + performAcmActivation(cmd, AcmActivationCompleted); } + break; } - }); + case 'ccmactivate': { + // Server responded with CCM activation response + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + settings.xxprofileScript = cmd.profileScript; + settings.xxrawpassword = cmd.rawpassword; + + // If we are already in CCM mode, deactivate. + if (mestate.controlMode == 1) { + amtMei.unprovision(1, function (status) { + if (status == 0) { + console.log('Intel AMT CCM deactivated, holding 10 seconds...'); + // We are ready to go, perform CCM activation. + settings.xxTimer = setTimeout(function () { osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation); }, 10000); + } else { + console.log('Intel AMT CCM deactivation error ' + status); exit(1); return; + } + }); + } else { + // We are ready to go, perform CCM activation. + osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation); + } + break; + } + case 'amtdiscover': { + console.log('Done.'); + exit(0); + break; + } + default: { + console.log('Invalid server response, command: ' + cmd.action); exit(100); + break; + } + } }); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate', fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'] }); + + var action = 'acmactivate'; + if (settings.action == 'amtccm') { action = 'ccmactivate'; } + if (settings.action == 'amtdiscover') { action = 'amtdiscover'; } + socket.write({ client: 'meshcmd', version: 1, action: action, fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'], modes: allowedModes, currentMode: mestate.controlMode }); }); connection.end(); } +function performCcmActivation(stack, name, responses, status) { + if (status != 200) { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); + console.log('Failed to activate, status ' + status); + } else if (responses.Body.ReturnValue != 0) { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); + console.log('Intel AMT CCM activation failed: ' + responses.Body.ReturnValueStr); + } else { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-success', uuid: mestate.uuid }); + if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) { + console.log("Intel AMT CCM activation success, applying profile..."); + settings.scriptjson = settings.xxprofileScript; + settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); + return; + } else { + console.log('Intel AMT CCM activation success.'); + settings.xxsocket.end(); + exit(0); + return; + } + } + settings.xxsocket.end(); + exit(1); +} + +function AcmActivationCompleted(result) { + if (result == false) { + console.log('Intel AMT ACM activation failed.'); + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-failed', uuid: mestate.uuid }); + settings.xxsocket.end(); + exit(1); + } else { + if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { + console.log('Intel AMT ACM activation success, applying profile...'); + settings.scriptjson = cmd.profileScript; + settings.password = cmd.rawpassword; // This is only going to work if the server sends the raw password + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); settings.xxsocket.end(); exit(0); }, stack); + } else { + console.log('Intel AMT ACM activation success.'); + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-success', uuid: mestate.uuid }); + settings.xxsocket.end(); + exit(0); + } + } +} + // Recursive function to inject the provisioning certificates into AMT in the proper order and completes ACM activation function performAcmActivation(acmdata, func) { var leaf = (acmdata.index == 0), root = (acmdata.index == (acmdata.certs.length - 1)); if ((acmdata.index < acmdata.certs.length) && (acmdata.certs[acmdata.index] != null)) { osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(acmdata.certs[acmdata.index], leaf, root, function (stack, name, responses, status) { - if (status !== 200) { debug('AddNextCertInChain status: ' + status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { console.log('AddNextCertInChain error: ' + responses['Body']['ReturnValue']); return; } + if (status !== 200) { console.log('AddNextCertInChain error, status=' + status); exit(1); return; } + else if (responses['Body']['ReturnValue'] !== 0) { console.log('AddNextCertInChain error: ' + responses['Body']['ReturnValue']); exit(1); return; } else { acmdata.index++; performAcmActivation(acmdata, func); } }); } else { - console.log(acmdata.password, acmdata.nonce, acmdata.signature); + //console.log(acmdata.password, acmdata.nonce, acmdata.signature); osamtstack.IPS_HostBasedSetupService_AdminSetup(2, acmdata.password, acmdata.nonce, 2, acmdata.signature, function (stack, name, responses, status) { if (status !== 200) { console.log('Error, AdminSetup status: ' + status); } @@ -1181,7 +1186,6 @@ function startMeScriptEx(callback, amtstack) { // FETCH ALL INTEL AMT STATE // - function saveEntireAmtState2() { console.log('Fetching all Intel AMT state, this may take a few minutes...'); var transport = require('amt-wsman-duk'); diff --git a/agents/meshcmd.min.js b/agents/meshcmd.min.js index 4a3d3e49..d105e332 100644 --- a/agents/meshcmd.min.js +++ b/agents/meshcmd.min.js @@ -517,13 +517,18 @@ function run(argv) { settings.protocol = 'http:'; settings.localport = 16992; debug(1, "Settings: " + JSON.stringify(settings)); - if (settings.password != null) { activeToCCM(); } else { activeServerCCM(); } + if (settings.password != null) { activeToCCM(); } else { activeToACM(); } } else if (settings.action == 'amtacm') { // Start activation to ACM if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; } if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; } debug(1, "Settings: " + JSON.stringify(settings)); activeToACM(); + } else if (settings.action == 'amtdiscover') { + // Intel AMT server discovery, tell the server the state of Intel AMT. + if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; } + debug(1, "Settings: " + JSON.stringify(settings)); + activeToACM(); } else if (settings.action == 'amtdeactivate') { // Deactivate CCM debug(1, "Settings: " + JSON.stringify(settings)); @@ -823,91 +828,6 @@ function activeToCCMEx3(stack, name, responses, status) { } -// -// Activate Intel AMT to CCM with server activation -// - -function activeServerCCM() { - settings.noconsole = true; - mestate = {}; - var amtMeiModule, amtMei; - try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } - amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); - amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); - amtMei.getVersion(function (val) { mestate.vers = {}; if (val != null) { for (var version in val.Versions) { mestate.vers[val.Versions[version].Description] = val.Versions[version].Version; } } }); - amtMei.getUuid(function (result) { - if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } - if ((mestate.vers == null) || (mestate.vers['AMT'] == null)) { console.log("Unable to get Intel AMT version."); exit(100); return; } - if (mestate.ProvisioningState == null) { console.log("Unable to read Intel AMT activation state."); exit(100); return; } - if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } - if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } - startLms(activeServerCCMEx); - }); -} - -function activeServerCCMEx(state) { - osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeServerCCMEx2); -} - -function activeServerCCMEx2(stack, name, responses, status) { - if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); } - else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); } - - // Establish WebSocket connection to activation server - var options = http.parseUri(settings.url); - options.checkServerIdentity = onVerifyServer; - options.rejectUnauthorized = false; - var connection = http.request(options); - connection.on('upgrade', function (response, socket) { - console.log('Connected, requesting activation...'); - settings.xxsocket = socket; - socket.on('end', function () { console.log('Connection closed'); exit(0); }); - socket.on('error', function () { console.log('Connection error'); exit(100); }); - socket.on('data', function (data) { - // Parse and check the response - var cmd = null; - try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } - if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } - if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } - if (cmd.action != 'ccmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } - if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } - settings.xxprofileScript = cmd.profileScript; - settings.xxrawpassword = cmd.rawpassword; - - // We are ready to go, perform CCM activation. - osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, activeServerCCMEx3); - }); - socket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate', realm: responses['AMT_GeneralSettings'].response['DigestRealm'], uuid: mestate.uuid, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'] }); - }); - connection.end(); -} - -function activeServerCCMEx3(stack, name, responses, status) { - if (status != 200) { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); - console.log('Failed to activate, status ' + status); - } else if (responses.Body.ReturnValue != 0) { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); - console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); - } else { - settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-success', uuid: mestate.uuid }); - if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) { - console.log("Intel AMT ACM activation success, applying profile..."); - settings.scriptjson = settings.xxprofileScript; - settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password - settings.username = 'admin'; - startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); - return; - } else { - console.log('Success'); - settings.xxsocket.end(); - exit(0); - return; - } - } - settings.xxsocket.end(); - exit(1); -} // @@ -976,11 +896,11 @@ function getTrustedHashes(amtMei, func, tag) { } // -// Activate Intel AMT to ACM +// Activate Intel AMT to with server (ACM or CCM) // function activeToACM() { - console.log('Starting Intel AMT provisioning to Admin Control Mode (ACM) attempt...'); + console.log('Starting Intel AMT activation attempt...'); settings.noconsole = true; // Display Intel AMT version and activation state @@ -992,10 +912,11 @@ function activeToACM() { amtMei.getVersion(function (val) { mestate.vers = {}; if (val != null) { for (var version in val.Versions) { mestate.vers[val.Versions[version].Description] = val.Versions[version].Version; } } }); amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getControlMode(function (result) { if (result != null) { mestate.controlMode = result.controlMode; } }); // controlMode: 0 = NoActivated, 1 = CCM, 2 = ACM amtMei.getDnsSuffix(function (result) { if ((mestate.vers == null) || (mestate.vers['AMT'] == null)) { console.log("Unable to get Intel AMT version."); exit(100); return; } if (mestate.ProvisioningState == null) { console.log("Unable to read Intel AMT activation state."); exit(100); return; } - if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } + if ((settings.action != 'amtdiscover') && (mestate.controlMode == 2)) { console.log("Intel AMT already activation in admin control mode."); exit(100); return; } if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } var fqdn = null; if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } @@ -1025,12 +946,13 @@ function getFwNonce() { if (status != 200) { console.log("Unable to get firmware activation nonce, status=" + status); exit(100); return; } var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce']; var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm']; - activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid); + var allowedModes = responses['IPS_HostBasedSetupService'].response['AllowedControlModes']; // 1 = CCM, 2 = ACM + activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid, allowedModes); }); } // Connect to the activation server and perform ACM activation -function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { +function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid, allowedModes) { console.log('FQDN: ' + dnsSuffix); console.log('UUID: ' + uuid); console.log('Realm: ' + digestRealm); @@ -1039,11 +961,11 @@ function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { // Establish WebSocket connection to activation server var options = http.parseUri(settings.url); - //options.checkServerIdentity = function (clientName, certs) { }; // TODO options.checkServerIdentity = onVerifyServer; options.rejectUnauthorized = false; var connection = http.request(options); connection.on('upgrade', function (response, socket) { + settings.xxsocket = socket; console.log('Connected, requesting activation...'); socket.on('end', function () { console.log('Connection closed'); exit(0); }); socket.on('error', function () { console.log('Connection error'); exit(100); }); @@ -1053,52 +975,135 @@ function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } - if (cmd.action != 'acmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } - if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } - if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } - if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } - if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } + switch (cmd.action) { + case 'acmactivate': { + // Server responded with ACM activation response + if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } + if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } - // We are ready to go, perform activation. - cmd.index = 0; - performAcmActivation(cmd, function (result) { - if (result == false) { - console.log('Intel AMT ACM activation failed.'); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-failed', uuid: mestate.uuid }); - socket.end(); - exit(1); - } else { - if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { - console.log('Intel AMT ACM activation success, applying profile...'); - settings.scriptjson = cmd.profileScript; - settings.password = cmd.rawpassword; // This is only going to work if the server sends the raw password - settings.username = 'admin'; - startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); + cmd.index = 0; + // If we are in CCM mode, deactivate. + if (mestate.controlMode == 1) { + amtMei.unprovision(1, function (status) { + if (status == 0) { + console.log('Intel AMT CCM deactivated, holding 10 seconds...'); + // We are ready to go, perform ACM activation. + settings.xxTimer = setTimeout(function () { performAcmActivation(cmd, AcmActivationCompleted); }, 10000); + } else { + console.log('Intel AMT CCM deactivation error ' + status); exit(1); return; + } + }); } else { - console.log('Intel AMT ACM activation success.'); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-success', uuid: mestate.uuid }); - socket.end(); - exit(0); + // We are ready to go, perform ACM activation. + performAcmActivation(cmd, AcmActivationCompleted); } + break; } - }); + case 'ccmactivate': { + // Server responded with CCM activation response + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + settings.xxprofileScript = cmd.profileScript; + settings.xxrawpassword = cmd.rawpassword; + + // If we are already in CCM mode, deactivate. + if (mestate.controlMode == 1) { + amtMei.unprovision(1, function (status) { + if (status == 0) { + console.log('Intel AMT CCM deactivated, holding 10 seconds...'); + // We are ready to go, perform CCM activation. + settings.xxTimer = setTimeout(function () { osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation); }, 10000); + } else { + console.log('Intel AMT CCM deactivation error ' + status); exit(1); return; + } + }); + } else { + // We are ready to go, perform CCM activation. + osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation); + } + break; + } + case 'amtdiscover': { + console.log('Done.'); + exit(0); + break; + } + default: { + console.log('Invalid server response, command: ' + cmd.action); exit(100); + break; + } + } }); - socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate', fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'] }); + + var action = 'acmactivate'; + if (settings.action == 'amtccm') { action = 'ccmactivate'; } + if (settings.action == 'amtdiscover') { action = 'amtdiscover'; } + socket.write({ client: 'meshcmd', version: 1, action: action, fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'], modes: allowedModes, currentMode: mestate.controlMode }); }); connection.end(); } +function performCcmActivation(stack, name, responses, status) { + if (status != 200) { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); + console.log('Failed to activate, status ' + status); + } else if (responses.Body.ReturnValue != 0) { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid }); + console.log('Intel AMT CCM activation failed: ' + responses.Body.ReturnValueStr); + } else { + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-success', uuid: mestate.uuid }); + if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) { + console.log("Intel AMT CCM activation success, applying profile..."); + settings.scriptjson = settings.xxprofileScript; + settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); + return; + } else { + console.log('Intel AMT CCM activation success.'); + settings.xxsocket.end(); + exit(0); + return; + } + } + settings.xxsocket.end(); + exit(1); +} + +function AcmActivationCompleted(result) { + if (result == false) { + console.log('Intel AMT ACM activation failed.'); + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-failed', uuid: mestate.uuid }); + settings.xxsocket.end(); + exit(1); + } else { + if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { + console.log('Intel AMT ACM activation success, applying profile...'); + settings.scriptjson = cmd.profileScript; + settings.password = cmd.rawpassword; // This is only going to work if the server sends the raw password + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); settings.xxsocket.end(); exit(0); }, stack); + } else { + console.log('Intel AMT ACM activation success.'); + settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-success', uuid: mestate.uuid }); + settings.xxsocket.end(); + exit(0); + } + } +} + // Recursive function to inject the provisioning certificates into AMT in the proper order and completes ACM activation function performAcmActivation(acmdata, func) { var leaf = (acmdata.index == 0), root = (acmdata.index == (acmdata.certs.length - 1)); if ((acmdata.index < acmdata.certs.length) && (acmdata.certs[acmdata.index] != null)) { osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(acmdata.certs[acmdata.index], leaf, root, function (stack, name, responses, status) { - if (status !== 200) { debug('AddNextCertInChain status: ' + status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { console.log('AddNextCertInChain error: ' + responses['Body']['ReturnValue']); return; } + if (status !== 200) { console.log('AddNextCertInChain error, status=' + status); exit(1); return; } + else if (responses['Body']['ReturnValue'] !== 0) { console.log('AddNextCertInChain error: ' + responses['Body']['ReturnValue']); exit(1); return; } else { acmdata.index++; performAcmActivation(acmdata, func); } }); } else { - console.log(acmdata.password, acmdata.nonce, acmdata.signature); + //console.log(acmdata.password, acmdata.nonce, acmdata.signature); osamtstack.IPS_HostBasedSetupService_AdminSetup(2, acmdata.password, acmdata.nonce, 2, acmdata.signature, function (stack, name, responses, status) { if (status !== 200) { console.log('Error, AdminSetup status: ' + status); } @@ -1181,7 +1186,6 @@ function startMeScriptEx(callback, amtstack) { // FETCH ALL INTEL AMT STATE // - function saveEntireAmtState2() { console.log('Fetching all Intel AMT state, this may take a few minutes...'); var transport = require('amt-wsman-duk'); diff --git a/webserver.js b/webserver.js index 89cc2bc4..1f2ff8be 100644 --- a/webserver.js +++ b/webserver.js @@ -2190,73 +2190,74 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Process the command switch (cmd.action) { - case 'ccmactivate': { + case 'amtdiscover': { + console.log(cmd); + ws.send(JSON.stringify({ action: 'amtdiscover' })); + ws.close(); + return; + } + case 'ccmactivate': + case 'acmactivate': { // Check the command if (cmd.version != 1) { ws.send(JSON.stringify({ errorText: 'Unsupported version' })); ws.close(); return; } if (obj.common.validateString(cmd.realm, 16, 256) == false) { ws.send(JSON.stringify({ errorText: 'Invalid realm argument' })); ws.close(); return; } if (obj.common.validateString(cmd.uuid, 36, 36) == false) { ws.send(JSON.stringify({ errorText: 'Invalid UUID argument' })); ws.close(); return; } - if ((obj.common.validateString(cmd.ver, 5, 16) == false) || (cmd.ver.split('.').length != 3)) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT version' })); ws.close(); return; } - - // Get the current Intel AMT policy - var mesh = obj.meshes[ws.meshid]; - if ((mesh == null) || (mesh.amt == null) || (mesh.amt.type != 2) || (mesh.amt.password == null)) { ws.send(JSON.stringify({ errorText: 'Unable to activate' })); ws.close(); return; } - - // Get the Intel AMT admin password, randomize if needed. - var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password); - if (checkAmtPassword(amtpassword) == false) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT password' })); ws.close(); return; } // Invalid Intel AMT password, this should never happen. - - // Log the activation request, logging is a required step for activation. - if (parent.certificateOperations.logAmtActivation(domain, { time: new Date(), action: 'ccmactivate', domain: domain.id, amtUuid: cmd.uuid, amtRealm: cmd.realm, user: 'admin', password: amtpassword, ipport: ws.remoteaddrport, meshid: ws.meshid, tag: cmd.tag, name: cmd.name }) == false) return { errorText: 'Unable to log operation' }; - - // Save some state, if activation is succesful, we need this to add the device - ws.xxstate = { uuid: cmd.uuid, realm: cmd.realm, tag: cmd.tag, name: cmd.name, pass: amtpassword, flags: 2, ver: cmd.ver }; // Flags 2 = CCM - - // Compute the HTTP digest hash and send the response - ws.send(JSON.stringify({ action: 'ccmactivate', password: obj.crypto.createHash('md5').update('admin:' + cmd.realm + ':' + amtpassword).digest('hex') })); - break; - } - case 'acmactivate': { - // Check the command - if (cmd.version != 1) { ws.send(JSON.stringify({ errorText: 'Unsupported version' })); ws.close(); return; } if (typeof cmd.hashes != 'object') { ws.send(JSON.stringify({ errorText: 'Invalid hashes' })); ws.close(); return; } if (typeof cmd.fqdn != 'string') { ws.send(JSON.stringify({ errorText: 'Invalid FQDN' })); ws.close(); return; } if ((obj.common.validateString(cmd.ver, 5, 16) == false) || (cmd.ver.split('.').length != 3)) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT version' })); ws.close(); return; } + if (obj.common.validateArray(cmd.modes, 1, 2) == false) { ws.send(JSON.stringify({ errorText: 'Invalid activation modes' })); ws.close(); return; } // Get the current Intel AMT policy - var mesh = obj.meshes[ws.meshid]; - if ((mesh == null) || (mesh.amt == null) || (mesh.amt.type != 3) || (domain.amtacmactivation == null) || (domain.amtacmactivation.acmmatch == null) || (mesh.amt.password == null)) { ws.send(JSON.stringify({ errorText: 'Unable to activate' })); ws.close(); return; } + var mesh = obj.meshes[ws.meshid], activationMode = 4; // activationMode: 2 = CCM, 4 = ACM + if ((mesh == null) || (mesh.amt == null) || (mesh.amt.password == null) || ((mesh.amt.type != 2) && (mesh.amt.type != 3))) { ws.send(JSON.stringify({ errorText: 'Unable to activate' })); ws.close(); return; } + if ((mesh.amt.type != 3) || (domain.amtacmactivation == null) || (domain.amtacmactivation.acmmatch == null)) { activationMode = 2; } - // Check if we have a FQDN/Hash match - var matchingHash = null, matchingCN = null; - for (var i in domain.amtacmactivation.acmmatch) { - // Check for a matching FQDN - if ((domain.amtacmactivation.acmmatch[i].cn == '*') || (domain.amtacmactivation.acmmatch[i].cn.toLowerCase() == cmd.fqdn)) { - // Check for a matching certificate - if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha256) >= 0) { - matchingCN = domain.amtacmactivation.acmmatch[i].cn; - matchingHash = domain.amtacmactivation.acmmatch[i].sha256; - continue; - } else if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha1) >= 0) { - matchingCN = domain.amtacmactivation.acmmatch[i].cn; - matchingHash = domain.amtacmactivation.acmmatch[i].sha1; - continue; + if (activationMode == 4) { + // Check if we have a FQDN/Hash match + var matchingHash = null, matchingCN = null; + for (var i in domain.amtacmactivation.acmmatch) { + // Check for a matching FQDN + if ((domain.amtacmactivation.acmmatch[i].cn == '*') || (domain.amtacmactivation.acmmatch[i].cn.toLowerCase() == cmd.fqdn)) { + // Check for a matching certificate + if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha256) >= 0) { + matchingCN = domain.amtacmactivation.acmmatch[i].cn; + matchingHash = domain.amtacmactivation.acmmatch[i].sha256; + continue; + } else if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha1) >= 0) { + matchingCN = domain.amtacmactivation.acmmatch[i].cn; + matchingHash = domain.amtacmactivation.acmmatch[i].sha1; + continue; + } } } + // If no cert match or wildcard match which is not yet supported, do CCM activation. + if ((matchingHash == null) || (matchingCN == '*')) { activationMode = 2; } else { cmd.hash = matchingHash; } } - if (matchingHash == null) { ws.send(JSON.stringify({ errorText: 'No matching activation certificates' })); ws.close(); return; } - if (matchingCN == '*') { ws.send(JSON.stringify({ errorText: 'Wildcard certificate activation not yet supported' })); ws.close(); return; } - cmd.hash = matchingHash; + + // Check if we are going to activate in an allowed mode. cmd.modes: 1 = CCM, 2 = ACM + if ((activationMode == 4) && (cmd.modes.indexOf(2) == -1)) { activationMode = 2; } // We want to do ACM, but mode is not allowed. Change to CCM. + + // If we want to do CCM, but mode is not allowed. Error out. + if ((activationMode == 2) && (cmd.modes.indexOf(1) == -1)) { ws.send(JSON.stringify({ errorText: 'Unsupported activation mode' })); ws.close(); return; } // Get the Intel AMT admin password, randomize if needed. var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password); if (checkAmtPassword(amtpassword) == false) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT password' })); ws.close(); return; } // Invalid Intel AMT password, this should never happen. // Save some state, if activation is succesful, we need this to add the device - ws.xxstate = { uuid: cmd.uuid, realm: cmd.realm, tag: cmd.tag, name: cmd.name, pass: amtpassword, flags: 4, ver: cmd.ver }; // Flags 4 = ACM + ws.xxstate = { uuid: cmd.uuid, realm: cmd.realm, tag: cmd.tag, name: cmd.name, pass: amtpassword, flags: activationMode, ver: cmd.ver }; // Flags: 2 = CCM, 4 = ACM - // Agent is asking the server to sign an Intel AMT ACM activation request - var signResponse = parent.certificateOperations.signAcmRequest(domain, cmd, 'admin', amtpassword, ws.remoteaddrport, null, ws.meshid, null, null); - ws.send(JSON.stringify(signResponse)); + if (activationMode == 4) { + // ACM: Agent is asking the server to sign an Intel AMT ACM activation request + var signResponse = parent.certificateOperations.signAcmRequest(domain, cmd, 'admin', amtpassword, ws.remoteaddrport, null, ws.meshid, null, null); + ws.send(JSON.stringify(signResponse)); + } else { + // CCM: Log the activation request, logging is a required step for activation. + if (parent.certificateOperations.logAmtActivation(domain, { time: new Date(), action: 'ccmactivate', domain: domain.id, amtUuid: cmd.uuid, amtRealm: cmd.realm, user: 'admin', password: amtpassword, ipport: ws.remoteaddrport, meshid: ws.meshid, tag: cmd.tag, name: cmd.name }) == false) return { errorText: 'Unable to log operation' }; + + // Compute the HTTP digest hash and send the response for CCM activation + ws.send(JSON.stringify({ action: 'ccmactivate', password: obj.crypto.createHash('md5').update('admin:' + cmd.realm + ':' + amtpassword).digest('hex') })); + } break; } case 'ccmactivate-failed': @@ -2929,6 +2930,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.app.ws(url + 'control.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); }); obj.app.get(url + 'logo.png', handleLogoRequest); obj.app.get(url + 'welcome.jpg', handleWelcomeImageRequest); + obj.app.ws(url + 'amtactivate', handleAmtActivateWebSocket); // Server redirects if (parent.config.domains[i].redirects) { for (var j in parent.config.domains[i].redirects) { if (j[0] != '_') { obj.app.get(url + j, handleDomainRedirect); } } } @@ -2967,11 +2969,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { }); } - // Intel AMT ACM activation - if ((parent.config.domains[i].amtacmactivation != null) && (parent.config.domains[i].amtacmactivation.acmmatch != null)) { - obj.app.ws(url + 'amtactivate', handleAmtActivateWebSocket); - } - // Creates a login token using the user/pass that is passed in as URL arguments. // For example: https://localhost/createLoginToken.ashx?user=admin&pass=admin&a=3 // It's not advised to use this to create login tokens since the URL is often logged and you got credentials in the URL.