libcli/auth: add netlogon_creds_[de|en]crypt_samlogon_logon()
authorStefan Metzmacher <metze@samba.org>
Thu, 25 Apr 2013 15:01:00 +0000 (17:01 +0200)
committerAndreas Schneider <asn@samba.org>
Mon, 5 Aug 2013 08:30:01 +0000 (10:30 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
libcli/auth/credentials.c
libcli/auth/proto.h

index 2e9c87e8f62f4b07e7b42b92da394065bf011d8b..78a8d7ad6c8fa1ea9f777ae60cc09d273e91c30c 100644 (file)
@@ -601,6 +601,124 @@ void netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_Credential
                                                        validation, true);
 }
 
+static void netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
+                                               enum netr_LogonInfoClass level,
+                                               union netr_LogonLevel *logon,
+                                               bool encrypt)
+{
+       static const char zeros[16];
+
+       if (logon == NULL) {
+               return;
+       }
+
+       switch (level) {
+       case NetlogonInteractiveInformation:
+       case NetlogonInteractiveTransitiveInformation:
+       case NetlogonServiceInformation:
+       case NetlogonServiceTransitiveInformation:
+               if (logon->password == NULL) {
+                       return;
+               }
+
+               if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+                       uint8_t *h;
+
+                       h = logon->password->lmpassword.hash;
+                       if (memcmp(h, zeros, 16) != 0) {
+                               if (encrypt) {
+                                       netlogon_creds_aes_encrypt(creds, h, 16);
+                               } else {
+                                       netlogon_creds_aes_decrypt(creds, h, 16);
+                               }
+                       }
+
+                       h = logon->password->ntpassword.hash;
+                       if (memcmp(h, zeros, 16) != 0) {
+                               if (encrypt) {
+                                       netlogon_creds_aes_encrypt(creds, h, 16);
+                               } else {
+                                       netlogon_creds_aes_decrypt(creds, h, 16);
+                               }
+                       }
+               } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+                       uint8_t *h;
+
+                       h = logon->password->lmpassword.hash;
+                       if (memcmp(h, zeros, 16) != 0) {
+                               netlogon_creds_arcfour_crypt(creds, h, 16);
+                       }
+
+                       h = logon->password->ntpassword.hash;
+                       if (memcmp(h, zeros, 16) != 0) {
+                               netlogon_creds_arcfour_crypt(creds, h, 16);
+                       }
+               } else {
+                       struct samr_Password *p;
+
+                       p = &logon->password->lmpassword;
+                       if (memcmp(p->hash, zeros, 16) != 0) {
+                               if (encrypt) {
+                                       netlogon_creds_des_encrypt(creds, p);
+                               } else {
+                                       netlogon_creds_des_decrypt(creds, p);
+                               }
+                       }
+                       p = &logon->password->ntpassword;
+                       if (memcmp(p->hash, zeros, 16) != 0) {
+                               if (encrypt) {
+                                       netlogon_creds_des_encrypt(creds, p);
+                               } else {
+                                       netlogon_creds_des_decrypt(creds, p);
+                               }
+                       }
+               }
+               break;
+
+       case NetlogonNetworkInformation:
+       case NetlogonNetworkTransitiveInformation:
+               break;
+
+       case NetlogonGenericInformation:
+               if (logon->generic == NULL) {
+                       return;
+               }
+
+               if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+                       if (encrypt) {
+                               netlogon_creds_aes_encrypt(creds,
+                                               logon->generic->data,
+                                               logon->generic->length);
+                       } else {
+                               netlogon_creds_aes_decrypt(creds,
+                                               logon->generic->data,
+                                               logon->generic->length);
+                       }
+               } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+                       netlogon_creds_arcfour_crypt(creds,
+                                                    logon->generic->data,
+                                                    logon->generic->length);
+               } else {
+                       /* Using DES to verify kerberos tickets makes no sense */
+               }
+               break;
+       }
+}
+
+void netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
+                                          enum netr_LogonInfoClass level,
+                                          union netr_LogonLevel *logon)
+{
+       netlogon_creds_crypt_samlogon_logon(creds, level, logon, false);
+}
+
+void netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
+                                          enum netr_LogonInfoClass level,
+                                          union netr_LogonLevel *logon)
+{
+       netlogon_creds_crypt_samlogon_logon(creds, level, logon, true);
+}
+
 /*
   copy a netlogon_creds_CredentialState struct
 */
index 6bc18d78205a554f2ea444de22fc4ddf3004be29..110e039eaecb523ad7d839906502cd8e44989f48 100644 (file)
@@ -64,6 +64,12 @@ void netlogon_creds_decrypt_samlogon_validation(struct netlogon_creds_Credential
 void netlogon_creds_encrypt_samlogon_validation(struct netlogon_creds_CredentialState *creds,
                                                uint16_t validation_level,
                                                union netr_Validation *validation);
+void netlogon_creds_decrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
+                                          enum netr_LogonInfoClass level,
+                                          union netr_LogonLevel *logon);
+void netlogon_creds_encrypt_samlogon_logon(struct netlogon_creds_CredentialState *creds,
+                                          enum netr_LogonInfoClass level,
+                                          union netr_LogonLevel *logon);
 
 /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/session.c  */