LCOV - code coverage report
Current view: top level - source4/torture/krb5 - kdc-mit.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 221 241 91.7 %
Date: 2024-04-21 15:09:00 Functions: 16 16 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Validate the krb5 pac generation routines
       5             : 
       6             :    Copyright (c) 2016      Andreas Schneider <asn@samba.org>
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/kerberos.h"
      24             : #include "system/time.h"
      25             : #include "torture/smbtorture.h"
      26             : #include "torture/winbind/proto.h"
      27             : #include "torture/krb5/proto.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "lib/cmdline/cmdline.h"
      30             : #include "source4/auth/kerberos/kerberos.h"
      31             : #include "source4/auth/kerberos/kerberos_util.h"
      32             : #include "lib/util/util_net.h"
      33             : 
      34             : #define krb5_is_app_tag(dat,tag)                          \
      35             :         ((dat != NULL) && (dat)->length &&                \
      36             :          ((((dat)->data[0] & ~0x20) == ((tag) | 0x40))))
      37             : 
      38             : #define krb5_is_as_req(dat)                   krb5_is_app_tag(dat, 10)
      39             : #define krb5_is_as_rep(dat)                   krb5_is_app_tag(dat, 11)
      40             : #define krb5_is_krb_error(dat)                krb5_is_app_tag(dat, 30)
      41             : 
      42             : enum torture_krb5_test {
      43             :         TORTURE_KRB5_TEST_PLAIN,
      44             :         TORTURE_KRB5_TEST_PAC_REQUEST,
      45             :         TORTURE_KRB5_TEST_BREAK_PW,
      46             :         TORTURE_KRB5_TEST_CLOCK_SKEW,
      47             :         TORTURE_KRB5_TEST_AES,
      48             :         TORTURE_KRB5_TEST_RC4,
      49             :         TORTURE_KRB5_TEST_AES_RC4,
      50             : };
      51             : 
      52             : struct torture_krb5_context {
      53             :         struct torture_context *tctx;
      54             :         krb5_context krb5_context;
      55             :         enum torture_krb5_test test;
      56             :         int recv_packet_count;
      57             :         krb5_kdc_req *as_req;
      58             :         krb5_kdc_rep *as_rep;
      59             : };
      60             : 
      61             : krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
      62             : 
      63             : krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
      64             : krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
      65             : 
      66             : krb5_error_code decode_krb5_padata_sequence(const krb5_data *output, krb5_pa_data ***rep);
      67             : 
      68             : void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
      69             : void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
      70             : void krb5_free_pa_data(krb5_context ctx, krb5_pa_data **data);
      71             : 
      72          25 : static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
      73             :                                       krb5_context context,
      74             :                                       const krb5_data *message)
      75             : {
      76             :         krb5_error_code code;
      77             :         int nktypes;
      78             : 
      79          25 :         code = decode_krb5_as_req(message, &test_context->as_req);
      80          25 :         torture_assert_int_equal(test_context->tctx,
      81             :                                  code, 0,
      82             :                                  "decode_as_req failed");
      83          25 :         torture_assert_int_equal(test_context->tctx,
      84             :                                  test_context->as_req->msg_type,
      85             :                                  KRB5_AS_REQ,
      86             :                                  "Not a AS REQ");
      87             : 
      88          25 :         nktypes = test_context->as_req->nktypes;
      89          25 :         torture_assert_int_not_equal(test_context->tctx,
      90             :                                      nktypes, 0,
      91             :                                      "No keytypes");
      92             : 
      93          25 :         return true;
      94             : }
      95             : 
      96          25 : static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
      97             :                                                   void *data,
      98             :                                                   const krb5_data *realm,
      99             :                                                   const krb5_data *message,
     100             :                                                   krb5_data **new_message_out,
     101             :                                                   krb5_data **new_reply_out)
     102             : {
     103             :         bool ok;
     104          25 :         struct torture_krb5_context *test_context =
     105             :                 (struct torture_krb5_context *)data;
     106             : 
     107          25 :         switch (test_context->test)
     108             :         {
     109          25 :         case TORTURE_KRB5_TEST_PLAIN:
     110             :         case TORTURE_KRB5_TEST_PAC_REQUEST:
     111             :         case TORTURE_KRB5_TEST_BREAK_PW:
     112             :         case TORTURE_KRB5_TEST_CLOCK_SKEW:
     113             :         case TORTURE_KRB5_TEST_AES:
     114             :         case TORTURE_KRB5_TEST_RC4:
     115             :         case TORTURE_KRB5_TEST_AES_RC4:
     116          25 :                 ok = torture_check_krb5_as_req(test_context,
     117             :                                                context,
     118             :                                                message);
     119          25 :                 if (!ok) {
     120           0 :                         return KRB5KDC_ERR_BADOPTION;
     121             :                 }
     122          25 :                 break;
     123             :         }
     124             : 
     125          25 :         return 0;
     126             : }
     127             : 
     128             : /*
     129             :  * We need these function to validate packets because our torture macros
     130             :  * do a 'return false' on error.
     131             :  */
     132          18 : static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
     133             :                                      krb5_context context,
     134             :                                      const krb5_data *reply,
     135             :                                      krb5_error_code error_code,
     136             :                                      bool check_pa_data)
     137             : 
     138             : {
     139             :         krb5_error *krb_error;
     140             :         krb5_error_code code;
     141             : 
     142          18 :         code = decode_krb5_error(reply, &krb_error);
     143          18 :         torture_assert_int_equal(test_context->tctx,
     144             :                                  code,
     145             :                                  0,
     146             :                                  "decode_krb5_error failed");
     147             : 
     148          18 :         torture_assert_int_equal(test_context->tctx,
     149             :                                  krb_error->error,
     150             :                                  error_code - KRB5KDC_ERR_NONE,
     151             :                                  "Got wrong error code");
     152             : 
     153          15 :         if (check_pa_data) {
     154           2 :                 krb5_pa_data **d, **pa_data = NULL;
     155           2 :                 bool timestamp_found = false;
     156             : 
     157           2 :                 torture_assert_int_not_equal(test_context->tctx,
     158             :                                              krb_error->e_data.length, 0,
     159             :                                              "No e-data returned");
     160             : 
     161           2 :                 code = decode_krb5_padata_sequence(&krb_error->e_data,
     162             :                                                    &pa_data);
     163           2 :                 torture_assert_int_equal(test_context->tctx,
     164             :                                          code,
     165             :                                          0,
     166             :                                          "decode_krb5_padata_sequence failed");
     167             : 
     168           7 :                 for (d = pa_data; d != NULL; d++) {
     169           7 :                         if ((*d)->pa_type == KRB5_PADATA_ENC_TIMESTAMP) {
     170           2 :                                 timestamp_found = true;
     171           2 :                                 break;
     172             :                         }
     173             :                 }
     174           2 :                 torture_assert(test_context->tctx,
     175             :                                timestamp_found,
     176             :                                "Encrypted timestamp not found");
     177             : 
     178           2 :                 krb5_free_pa_data(context, pa_data);
     179             :         }
     180             : 
     181          15 :         krb5_free_error(context, krb_error);
     182             : 
     183          15 :         return true;
     184             : }
     185             : 
     186           7 : static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
     187             :                                       krb5_context context,
     188             :                                       const krb5_data *reply)
     189             : {
     190             :         krb5_error_code code;
     191             :         bool ok;
     192             : 
     193           7 :         code = decode_krb5_as_rep(reply, &test_context->as_rep);
     194           7 :         torture_assert_int_equal(test_context->tctx,
     195             :                                  code,
     196             :                                  0,
     197             :                                  "decode_krb5_as_rep failed");
     198             : 
     199           7 :         torture_assert(test_context->tctx,
     200             :                        test_context->as_rep->ticket->enc_part.kvno,
     201             :                        "No KVNO set");
     202             : 
     203           7 :         ok = torture_setting_bool(test_context->tctx,
     204             :                                   "expect_cached_at_rodc",
     205             :                                   false);
     206           7 :         if (ok) {
     207           0 :                 torture_assert_int_not_equal(test_context->tctx,
     208             :                                              test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
     209             :                                              0,
     210             :                                              "Did not get a RODC number in the KVNO");
     211             :         } else {
     212           7 :                 torture_assert_int_equal(test_context->tctx,
     213             :                                          test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
     214             :                                          0,
     215             :                                          "Unexpecedly got a RODC number in the KVNO");
     216             :         }
     217             : 
     218           7 :         return true;
     219             : }
     220             : 
     221           5 : static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
     222             :                                               krb5_context context,
     223             :                                               const krb5_data *reply,
     224             :                                               krb5_enctype expected_enctype)
     225             : {
     226             :         krb5_enctype reply_enctype;
     227             :         bool ok;
     228             : 
     229           5 :         ok = torture_check_krb5_as_rep(test_context,
     230             :                                        context,
     231             :                                        reply);
     232           5 :         if (!ok) {
     233           0 :                 return false;
     234             :         }
     235             : 
     236           5 :         reply_enctype = test_context->as_rep->enc_part.enctype;
     237             : 
     238           5 :         torture_assert_int_equal(test_context->tctx,
     239             :                                  reply_enctype, expected_enctype,
     240             :                                  "Ticket encrypted with invalid algorithm");
     241             : 
     242           4 :         return true;
     243             : }
     244             : 
     245          25 : static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
     246             :                                                    void *data,
     247             :                                                    krb5_error_code kdc_code,
     248             :                                                    const krb5_data *realm,
     249             :                                                    const krb5_data *message,
     250             :                                                    const krb5_data *reply,
     251             :                                                    krb5_data **new_reply_out)
     252             : {
     253          25 :         struct torture_krb5_context *test_context =
     254             :                 (struct torture_krb5_context *)data;
     255             :         krb5_error_code code;
     256          25 :         bool ok = true;
     257             : 
     258          25 :         torture_comment(test_context->tctx,
     259             :                         "PACKET COUNT = %d\n",
     260             :                         test_context->recv_packet_count);
     261             : 
     262          50 :         torture_comment(test_context->tctx,
     263             :                         "KRB5_AS_REP = %d\n",
     264          25 :                         krb5_is_as_req(reply));
     265             : 
     266          50 :         torture_comment(test_context->tctx,
     267             :                         "KRB5_ERROR = %d\n",
     268          25 :                         krb5_is_krb_error(reply));
     269             : 
     270          25 :         torture_comment(test_context->tctx,
     271             :                         "KDC ERROR CODE = %d\n",
     272             :                         kdc_code);
     273             : 
     274          25 :         switch (test_context->test)
     275             :         {
     276           4 :         case TORTURE_KRB5_TEST_PLAIN:
     277           4 :                 if (test_context->recv_packet_count == 0) {
     278           2 :                         ok = torture_check_krb5_error(test_context,
     279             :                                                       context,
     280             :                                                       reply,
     281             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     282             :                                                       false);
     283           2 :                         torture_assert_goto(test_context->tctx,
     284             :                                             ok,
     285             :                                             ok,
     286             :                                             out,
     287             :                                             "torture_check_krb5_error failed");
     288             :                 } else {
     289           2 :                         ok = torture_check_krb5_as_rep(test_context,
     290             :                                                        context,
     291             :                                                        reply);
     292           2 :                         torture_assert_goto(test_context->tctx,
     293             :                                             ok,
     294             :                                             ok,
     295             :                                             out,
     296             :                                             "torture_check_krb5_as_rep failed");
     297             :                 }
     298             : 
     299           4 :                 torture_assert_goto(test_context->tctx,
     300             :                                     test_context->recv_packet_count < 2,
     301             :                                     ok,
     302             :                                     out,
     303             :                                     "Too many packets");
     304             : 
     305           4 :                 break;
     306           2 :         case TORTURE_KRB5_TEST_PAC_REQUEST:
     307           2 :                 if (test_context->recv_packet_count == 0) {
     308           2 :                         ok = torture_check_krb5_error(test_context,
     309             :                                                       context,
     310             :                                                       reply,
     311             :                                                       KRB5KRB_ERR_RESPONSE_TOO_BIG,
     312             :                                                       false);
     313           2 :                         torture_assert_goto(test_context->tctx,
     314             :                                             ok,
     315             :                                             ok,
     316             :                                             out,
     317             :                                             "torture_check_krb5_error failed");
     318           0 :                 } else if (test_context->recv_packet_count == 1) {
     319           0 :                         ok = torture_check_krb5_error(test_context,
     320             :                                                       context,
     321             :                                                       reply,
     322             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     323             :                                                       false);
     324           0 :                         torture_assert_goto(test_context->tctx,
     325             :                                             ok,
     326             :                                             ok,
     327             :                                             out,
     328             :                                             "torture_check_krb5_error failed");
     329           0 :                 } else if (krb5_is_krb_error(reply)) {
     330           0 :                         ok = torture_check_krb5_error(test_context,
     331             :                                                       context,
     332             :                                                       reply,
     333             :                                                       KRB5KRB_ERR_RESPONSE_TOO_BIG,
     334             :                                                       false);
     335           0 :                         torture_assert_goto(test_context->tctx,
     336             :                                             ok,
     337             :                                             ok,
     338             :                                             out,
     339             :                                             "torture_check_krb5_error failed");
     340             :                 } else {
     341           0 :                         ok = torture_check_krb5_as_rep(test_context,
     342             :                                                        context,
     343             :                                                        reply);
     344           0 :                         torture_assert_goto(test_context->tctx,
     345             :                                             ok,
     346             :                                             ok,
     347             :                                             out,
     348             :                                             "torture_check_krb5_as_rep failed");
     349             :                 }
     350             : 
     351           0 :                 torture_assert_goto(test_context->tctx,
     352             :                                     test_context->recv_packet_count < 3,
     353             :                                     ok,
     354             :                                     out,
     355             :                                     "Too many packets");
     356           0 :                 break;
     357           4 :         case TORTURE_KRB5_TEST_BREAK_PW:
     358           4 :                 if (test_context->recv_packet_count == 0) {
     359           2 :                         ok = torture_check_krb5_error(test_context,
     360             :                                                       context,
     361             :                                                       reply,
     362             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     363             :                                                       false);
     364           2 :                         torture_assert_goto(test_context->tctx,
     365             :                                             ok,
     366             :                                             ok,
     367             :                                             out,
     368             :                                             "torture_check_krb5_error failed");
     369           2 :                         if (!ok) {
     370           0 :                                 goto out;
     371             :                         }
     372           2 :                 } else if (test_context->recv_packet_count == 1) {
     373           2 :                         ok = torture_check_krb5_error(test_context,
     374             :                                                       context,
     375             :                                                       reply,
     376             :                                                       KRB5KDC_ERR_PREAUTH_FAILED,
     377             :                                                       true);
     378           2 :                         torture_assert_goto(test_context->tctx,
     379             :                                             ok,
     380             :                                             ok,
     381             :                                             out,
     382             :                                             "torture_check_krb5_error failed");
     383             :                 }
     384             : 
     385           4 :                 torture_assert_goto(test_context->tctx,
     386             :                                     test_context->recv_packet_count < 2,
     387             :                                     ok,
     388             :                                     out,
     389             :                                     "Too many packets");
     390           4 :                 break;
     391           4 :         case TORTURE_KRB5_TEST_CLOCK_SKEW:
     392           4 :                 if (test_context->recv_packet_count == 0) {
     393           2 :                         ok = torture_check_krb5_error(test_context,
     394             :                                                       context,
     395             :                                                       reply,
     396             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     397             :                                                       false);
     398           2 :                         torture_assert_goto(test_context->tctx,
     399             :                                             ok,
     400             :                                             ok,
     401             :                                             out,
     402             :                                             "torture_check_krb5_error failed");
     403           2 :                         if (!ok) {
     404           0 :                                 goto out;
     405             :                         }
     406           2 :                 } else if (test_context->recv_packet_count == 1) {
     407             :                         /*
     408             :                          * This only works if kdc_timesync 0 is set in krb5.conf
     409             :                          *
     410             :                          * See commit 5f39a4438eafd693a3eb8366bbc3901efe62e538
     411             :                          * in the MIT Kerberos source tree.
     412             :                          */
     413           2 :                         ok = torture_check_krb5_error(test_context,
     414             :                                                       context,
     415             :                                                       reply,
     416             :                                                       KRB5KRB_AP_ERR_SKEW,
     417             :                                                       false);
     418           2 :                         torture_assert_goto(test_context->tctx,
     419             :                                             ok,
     420             :                                             ok,
     421             :                                             out,
     422             :                                             "torture_check_krb5_error failed");
     423             :                 }
     424             : 
     425           4 :                 torture_assert_goto(test_context->tctx,
     426             :                                     test_context->recv_packet_count < 2,
     427             :                                     ok,
     428             :                                     out,
     429             :                                     "Too many packets");
     430           4 :                 break;
     431           3 :         case TORTURE_KRB5_TEST_AES:
     432           3 :                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES\n");
     433             : 
     434           3 :                 if (test_context->recv_packet_count == 0) {
     435           2 :                         ok = torture_check_krb5_error(test_context,
     436             :                                                       context,
     437             :                                                       reply,
     438             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     439             :                                                       false);
     440           2 :                         if (!ok) {
     441           1 :                                 goto out;
     442             :                         }
     443             :                 } else {
     444           1 :                         ok = torture_check_krb5_as_rep_enctype(test_context,
     445             :                                                                context,
     446             :                                                                reply,
     447             :                                                                ENCTYPE_AES256_CTS_HMAC_SHA1_96);
     448           1 :                         if (!ok) {
     449           0 :                                 goto out;
     450             :                         }
     451             :                 }
     452           2 :                 break;
     453           4 :         case TORTURE_KRB5_TEST_RC4:
     454           4 :                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_RC4\n");
     455             : 
     456           4 :                 if (test_context->recv_packet_count == 0) {
     457           2 :                         ok = torture_check_krb5_error(test_context,
     458             :                                                       context,
     459             :                                                       reply,
     460             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     461             :                                                       false);
     462           2 :                         if (!ok) {
     463           0 :                                 goto out;
     464             :                         }
     465             :                 } else {
     466           2 :                         ok = torture_check_krb5_as_rep_enctype(test_context,
     467             :                                                                context,
     468             :                                                                reply,
     469             :                                                                ENCTYPE_ARCFOUR_HMAC);
     470           2 :                         if (!ok) {
     471           0 :                                 goto out;
     472             :                         }
     473             :                 }
     474           4 :                 break;
     475           4 :         case TORTURE_KRB5_TEST_AES_RC4:
     476           4 :                 torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES_RC4\n");
     477             : 
     478           4 :                 if (test_context->recv_packet_count == 0) {
     479           2 :                         ok = torture_check_krb5_error(test_context,
     480             :                                                       context,
     481             :                                                       reply,
     482             :                                                       KRB5KDC_ERR_PREAUTH_REQUIRED,
     483             :                                                       false);
     484           2 :                         if (!ok) {
     485           0 :                                 goto out;
     486             :                         }
     487             :                 } else {
     488           2 :                         ok = torture_check_krb5_as_rep_enctype(test_context,
     489             :                                                                context,
     490             :                                                                reply,
     491             :                                                                ENCTYPE_AES256_CTS_HMAC_SHA1_96);
     492           2 :                         if (!ok) {
     493           1 :                                 goto out;
     494             :                         }
     495             :                 }
     496           3 :                 break;
     497             :         }
     498             : 
     499          21 :         code = kdc_code;
     500          25 : out:
     501          25 :         if (!ok) {
     502           4 :                 code = EINVAL;
     503             :         }
     504             : 
     505             :         /* Cleanup */
     506          25 :         krb5_free_kdc_req(test_context->krb5_context, test_context->as_req);
     507          25 :         krb5_free_kdc_rep(test_context->krb5_context, test_context->as_rep);
     508             : 
     509          25 :         test_context->recv_packet_count++;
     510             : 
     511          25 :         return code;
     512             : }
     513             : 
     514          14 : static bool torture_krb5_init_context(struct torture_context *tctx,
     515             :                                       enum torture_krb5_test test,
     516             :                                       struct smb_krb5_context **smb_krb5_context)
     517             : {
     518             :         krb5_error_code code;
     519             : 
     520          14 :         struct torture_krb5_context *test_context = talloc_zero(tctx,
     521             :                                                                 struct torture_krb5_context);
     522          14 :         torture_assert(tctx, test_context != NULL, "Failed to allocate");
     523             : 
     524          14 :         test_context->test = test;
     525          14 :         test_context->tctx = tctx;
     526             : 
     527          14 :         code = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
     528          14 :         torture_assert_int_equal(tctx, code, 0, "smb_krb5_init_context failed");
     529             : 
     530          14 :         test_context->krb5_context = (*smb_krb5_context)->krb5_context;
     531             : 
     532          14 :         krb5_set_kdc_send_hook((*smb_krb5_context)->krb5_context,
     533             :                                torture_krb5_pre_send_test,
     534             :                                test_context);
     535             : 
     536          14 :         krb5_set_kdc_recv_hook((*smb_krb5_context)->krb5_context,
     537             :                                torture_krb5_post_recv_test,
     538             :                                test_context);
     539             : 
     540          14 :         return true;
     541             : }
     542          14 : static bool torture_krb5_as_req_creds(struct torture_context *tctx,
     543             :                                       struct cli_credentials *credentials,
     544             :                                       enum torture_krb5_test test)
     545             : {
     546          14 :         krb5_get_init_creds_opt *krb_options = NULL;
     547             :         struct smb_krb5_context *smb_krb5_context;
     548             :         enum credentials_obtained obtained;
     549             :         const char *error_string;
     550             :         const char *password;
     551             :         krb5_principal principal;
     552             :         krb5_error_code code;
     553             :         krb5_creds my_creds;
     554             :         bool ok;
     555             : 
     556          14 :         ok = torture_krb5_init_context(tctx, test, &smb_krb5_context);
     557          14 :         torture_assert(tctx, ok, "torture_krb5_init_context failed");
     558             : 
     559          14 :         code = principal_from_credentials(tctx,
     560             :                                           credentials,
     561             :                                           smb_krb5_context,
     562             :                                           &principal,
     563             :                                           &obtained,
     564             :                                           &error_string);
     565          14 :         torture_assert_int_equal(tctx, code, 0, error_string);
     566             : 
     567          14 :         password = cli_credentials_get_password(credentials);
     568             : 
     569          14 :         switch (test)
     570             :         {
     571           2 :         case TORTURE_KRB5_TEST_PLAIN:
     572           2 :                 break;
     573           2 :         case TORTURE_KRB5_TEST_PAC_REQUEST:
     574             : #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
     575           2 :                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
     576             :                                                      &krb_options);
     577           2 :                 torture_assert_int_equal(tctx,
     578             :                                          code, 0,
     579             :                                          "krb5_get_init_creds_opt_alloc failed");
     580             : 
     581           2 :                 code = krb5_get_init_creds_opt_set_pac_request(smb_krb5_context->krb5_context,
     582             :                                                                krb_options,
     583             :                                                                1);
     584           2 :                 torture_assert_int_equal(tctx,
     585             :                                          code, 0,
     586             :                                          "krb5_get_init_creds_opt_set_pac_request failed");
     587             : #endif
     588           2 :                 break;
     589           2 :         case TORTURE_KRB5_TEST_BREAK_PW:
     590           2 :                 password = "NOT the password";
     591           2 :                 break;
     592           2 :         case TORTURE_KRB5_TEST_CLOCK_SKEW:
     593           2 :                 code = krb5_set_real_time(smb_krb5_context->krb5_context,
     594           2 :                                           time(NULL) + 3600,
     595             :                                           0);
     596           2 :                 torture_assert_int_equal(tctx,
     597             :                                          code, 0,
     598             :                                          "krb5_set_real_time failed");
     599           2 :                 break;
     600           2 :         case TORTURE_KRB5_TEST_AES: {
     601           2 :                 krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96 };
     602             : 
     603           2 :                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
     604             :                                                      &krb_options);
     605           2 :                 torture_assert_int_equal(tctx,
     606             :                                          code, 0,
     607             :                                          "krb5_get_init_creds_opt_alloc failed");
     608             : 
     609           2 :                 krb5_get_init_creds_opt_set_etype_list(krb_options,
     610             :                                                        etype,
     611             :                                                        1);
     612           2 :                 break;
     613             :         }
     614           2 :         case TORTURE_KRB5_TEST_RC4: {
     615           2 :                 krb5_enctype etype[] = { ENCTYPE_ARCFOUR_HMAC };
     616             : 
     617           2 :                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
     618             :                                                      &krb_options);
     619           2 :                 torture_assert_int_equal(tctx,
     620             :                                          code, 0,
     621             :                                          "krb5_get_init_creds_opt_alloc failed");
     622             : 
     623           2 :                 krb5_get_init_creds_opt_set_etype_list(krb_options,
     624             :                                                        etype,
     625             :                                                        1);
     626           2 :                 break;
     627             :         }
     628           2 :         case TORTURE_KRB5_TEST_AES_RC4: {
     629           2 :                 krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_ARCFOUR_HMAC };
     630             : 
     631           2 :                 code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
     632             :                                                      &krb_options);
     633           2 :                 torture_assert_int_equal(tctx,
     634             :                                          code, 0,
     635             :                                          "krb5_get_init_creds_opt_alloc failed");
     636             : 
     637             : 
     638           2 :                 krb5_get_init_creds_opt_set_etype_list(krb_options,
     639             :                                                        etype,
     640             :                                                        2);
     641           2 :                 break;
     642             :         }
     643             :         }
     644             : 
     645          14 :         code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
     646             :                                             &my_creds,
     647             :                                             principal,
     648             :                                             password,
     649             :                                             NULL,
     650             :                                             NULL,
     651             :                                             0,
     652             :                                             NULL,
     653             :                                             krb_options);
     654          14 :         krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context,
     655             :                                      krb_options);
     656             : 
     657          14 :         switch (test)
     658             :         {
     659          10 :         case TORTURE_KRB5_TEST_PLAIN:
     660             :         case TORTURE_KRB5_TEST_PAC_REQUEST:
     661             :         case TORTURE_KRB5_TEST_AES:
     662             :         case TORTURE_KRB5_TEST_RC4:
     663             :         case TORTURE_KRB5_TEST_AES_RC4:
     664          10 :                 torture_assert_int_equal(tctx,
     665             :                                          code,
     666             :                                          0,
     667             :                                          "krb5_get_init_creds_password failed");
     668           6 :                 break;
     669           2 :         case TORTURE_KRB5_TEST_BREAK_PW:
     670           2 :                 torture_assert_int_equal(tctx,
     671             :                                          code,
     672             :                                          KRB5KDC_ERR_PREAUTH_FAILED,
     673             :                                          "krb5_get_init_creds_password should "
     674             :                                          "have failed");
     675           2 :                 return true;
     676           2 :         case TORTURE_KRB5_TEST_CLOCK_SKEW:
     677           2 :                 torture_assert_int_equal(tctx,
     678             :                                          code,
     679             :                                          KRB5KRB_AP_ERR_SKEW,
     680             :                                          "krb5_get_init_creds_password should "
     681             :                                          "have failed");
     682           2 :                 return true;
     683             :         }
     684             : 
     685           6 :         krb5_free_cred_contents(smb_krb5_context->krb5_context,
     686             :                                 &my_creds);
     687             : 
     688           6 :         return true;
     689             : }
     690             : 
     691           2 : static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
     692             : {
     693           2 :         return torture_krb5_as_req_creds(tctx,
     694             :                                          samba_cmdline_get_creds(),
     695             :                                          TORTURE_KRB5_TEST_PLAIN);
     696             : }
     697             : 
     698             : #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
     699           2 : static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
     700             : {
     701             :         bool ok;
     702             : 
     703           2 :         ok = torture_setting_bool(tctx, "expect_rodc", false);
     704           2 :         if (ok) {
     705           0 :                 torture_skip(tctx,
     706             :                              "This test needs further investigation in the "
     707             :                              "RODC case against a Windows DC, in particular "
     708             :                              "with non-cached users");
     709             :         }
     710           2 :         return torture_krb5_as_req_creds(tctx, samba_cmdline_get_creds(),
     711             :                         TORTURE_KRB5_TEST_PAC_REQUEST);
     712             : }
     713             : #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
     714             : 
     715           2 : static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
     716             : {
     717           2 :         return torture_krb5_as_req_creds(tctx,
     718             :                                          samba_cmdline_get_creds(),
     719             :                                          TORTURE_KRB5_TEST_BREAK_PW);
     720             : }
     721             : 
     722           2 : static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
     723             : {
     724           2 :         return torture_krb5_as_req_creds(tctx,
     725             :                                          samba_cmdline_get_creds(),
     726             :                                          TORTURE_KRB5_TEST_CLOCK_SKEW);
     727             : }
     728             : 
     729           2 : static bool torture_krb5_as_req_aes(struct torture_context *tctx)
     730             : {
     731           2 :         return torture_krb5_as_req_creds(tctx,
     732             :                                          samba_cmdline_get_creds(),
     733             :                                          TORTURE_KRB5_TEST_AES);
     734             : }
     735             : 
     736           2 : static bool torture_krb5_as_req_rc4(struct torture_context *tctx)
     737             : {
     738           2 :         return torture_krb5_as_req_creds(tctx,
     739             :                                          samba_cmdline_get_creds(),
     740             :                                          TORTURE_KRB5_TEST_RC4);
     741             : }
     742             : 
     743           2 : static bool torture_krb5_as_req_aes_rc4(struct torture_context *tctx)
     744             : {
     745           2 :         return torture_krb5_as_req_creds(tctx,
     746             :                                          samba_cmdline_get_creds(),
     747             :                                          TORTURE_KRB5_TEST_AES_RC4);
     748             : }
     749             : 
     750         438 : NTSTATUS torture_krb5_init(TALLOC_CTX *ctx)
     751             : {
     752             :         struct torture_suite *suite =
     753         438 :                 torture_suite_create(ctx, "krb5");
     754         438 :         struct torture_suite *kdc_suite = torture_suite_create(suite, "kdc");
     755         438 :         suite->description = talloc_strdup(suite, "Kerberos tests");
     756         438 :         kdc_suite->description = talloc_strdup(kdc_suite, "Kerberos KDC tests");
     757             : 
     758         438 :         torture_suite_add_simple_test(kdc_suite,
     759             :                                       "as-req-cmdline",
     760             :                                       torture_krb5_as_req_cmdline);
     761             : 
     762             : #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
     763             :         /* Only available with MIT Kerveros 1.15 and newer */
     764         438 :         torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
     765             :                                       torture_krb5_as_req_pac_request);
     766             : #endif
     767             : 
     768         438 :         torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
     769             :                                       torture_krb5_as_req_break_pw);
     770             : 
     771             :         /* This only works if kdc_timesync 0 is set in krb5.conf */
     772         438 :         torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
     773             :                                       torture_krb5_as_req_clock_skew);
     774             : 
     775             : #if 0
     776             :         torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
     777             : #endif
     778         438 :         torture_suite_add_simple_test(kdc_suite,
     779             :                                       "as-req-aes",
     780             :                                       torture_krb5_as_req_aes);
     781             : 
     782         438 :         torture_suite_add_simple_test(kdc_suite,
     783             :                                       "as-req-rc4",
     784             :                                       torture_krb5_as_req_rc4);
     785             : 
     786         438 :         torture_suite_add_simple_test(kdc_suite,
     787             :                                       "as-req-aes-rc4",
     788             :                                       torture_krb5_as_req_aes_rc4);
     789             : 
     790         438 :         torture_suite_add_suite(suite, kdc_suite);
     791             : 
     792         438 :         torture_register_suite(ctx, suite);
     793             : 
     794         438 :         return NT_STATUS_OK;
     795             : }

Generated by: LCOV version 1.14