/*
 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * ===========================================================================
 * (C) Copyright IBM Corp. 2000 All Rights Reserved.
 * ===========================================================================
 */

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <stdio.h>
#include <string.h>
#define SECURITY_WIN32
#include <security.h>
#include <ntsecapi.h>
#include <dsgetdc.h>
#include <lmcons.h>
#include <lmapibuf.h>
#include <jni.h>
#include <winsock.h>

#undef LSA_SUCCESS
#define LSA_SUCCESS(Status) ((Status) >= 0)
#define EXIT_FAILURE -1 // mdu

/*
 * Library-wide static references
 */

jclass derValueClass = NULL;
jclass ticketClass = NULL;
jclass principalNameClass = NULL;
jclass encryptionKeyClass = NULL;
jclass ticketFlagsClass = NULL;
jclass kerberosTimeClass = NULL;
jclass javaLangStringClass = NULL;

jmethodID derValueConstructor = 0;
jmethodID ticketConstructor = 0;
jmethodID principalNameConstructor = 0;
jmethodID encryptionKeyConstructor = 0;
jmethodID ticketFlagsConstructor = 0;
jmethodID kerberosTimeConstructor = 0;
jmethodID krbcredsConstructor = 0;
jmethodID setRealmMethod = 0;

/*
 * Function prototypes for internal routines
 *
 */
BOOL native_debug = 0;

BOOL PackageConnectLookup(PHANDLE,PULONG);

NTSTATUS ConstructTicketRequest(UNICODE_STRING DomainName,
                                PKERB_RETRIEVE_TKT_REQUEST *outRequest,
                                ULONG *outSize);

DWORD ConcatenateUnicodeStrings(UNICODE_STRING *pTarget,
                                UNICODE_STRING Source1,
                                UNICODE_STRING Source2);

VOID ShowNTError(LPSTR,NTSTATUS);

VOID
InitUnicodeString(
    PUNICODE_STRING DestinationString,
    PCWSTR SourceString OPTIONAL
);

jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize);

//mdu
jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName,
                                UNICODE_STRING domainName);

jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey);
jobject BuildTicketFlags(JNIEnv *env, PULONG flags);
jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime);

/*
 * Class:     sun_security_krb5_KrbCreds
 * Method:    JNI_OnLoad
 */

JNIEXPORT jint JNICALL JNI_OnLoad(
        JavaVM  *jvm,
        void    *reserved) {

    jclass cls;
    JNIEnv *env;
    jfieldID fldDEBUG;

    if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
        return JNI_EVERSION; /* JNI version not supported */
    }

    cls = (*env)->FindClass(env,"sun/security/krb5/internal/Krb5");
    if (cls == NULL) {
        printf("LSA: Couldn't find Krb5\n");
        return JNI_ERR;
    }
    fldDEBUG = (*env)->GetStaticFieldID(env, cls, "DEBUG", "Z");
    if (fldDEBUG == NULL) {
        printf("LSA: Krb5 has no DEBUG field\n");
        return JNI_ERR;
    }
    native_debug = (*env)->GetStaticBooleanField(env, cls, fldDEBUG);

    cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket");

    if (cls == NULL) {
        printf("LSA: Couldn't find Ticket\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found Ticket\n");
    }

    ticketClass = (*env)->NewWeakGlobalRef(env,cls);
    if (ticketClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName");

    if (cls == NULL) {
        printf("LSA: Couldn't find PrincipalName\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found PrincipalName\n");
    }

    principalNameClass = (*env)->NewWeakGlobalRef(env,cls);
    if (principalNameClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env,"sun/security/util/DerValue");

    if (cls == NULL) {
        printf("LSA: Couldn't find DerValue\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found DerValue\n");
    }

    derValueClass = (*env)->NewWeakGlobalRef(env,cls);
    if (derValueClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey");

    if (cls == NULL) {
        printf("LSA: Couldn't find EncryptionKey\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found EncryptionKey\n");
    }

    encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls);
    if (encryptionKeyClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags");

    if (cls == NULL) {
        printf("LSA: Couldn't find TicketFlags\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found TicketFlags\n");
    }

    ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls);
    if (ticketFlagsClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime");

    if (cls == NULL) {
        printf("LSA: Couldn't find KerberosTime\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found KerberosTime\n");
    }

    kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls);
    if (kerberosTimeClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    cls = (*env)->FindClass(env,"java/lang/String");

    if (cls == NULL) {
        printf("LSA: Couldn't find String\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found String\n");
    }

    javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls);
    if (javaLangStringClass == NULL) {
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Made NewWeakGlobalRef\n");
    }

    derValueConstructor = (*env)->GetMethodID(env, derValueClass,
                                            "<init>", "([B)V");
    if (derValueConstructor == 0) {
        printf("LSA: Couldn't find DerValue constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found DerValue constructor\n");
    }

    ticketConstructor = (*env)->GetMethodID(env, ticketClass,
                            "<init>", "(Lsun/security/util/DerValue;)V");
    if (ticketConstructor == 0) {
        printf("LSA: Couldn't find Ticket constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found Ticket constructor\n");
    }

    principalNameConstructor = (*env)->GetMethodID(env, principalNameClass,
                                    "<init>", "([Ljava/lang/String;)V");
    if (principalNameConstructor == 0) {
        printf("LSA: Couldn't find PrincipalName constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found PrincipalName constructor\n");
    }

    encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass,
                                            "<init>", "(I[B)V");
    if (encryptionKeyConstructor == 0) {
        printf("LSA: Couldn't find EncryptionKey constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found EncryptionKey constructor\n");
    }

    ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass,
                                            "<init>", "(I[B)V");
    if (ticketFlagsConstructor == 0) {
        printf("LSA: Couldn't find TicketFlags constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found TicketFlags constructor\n");
    }

    kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass,
                                    "<init>", "(Ljava/lang/String;)V");
    if (kerberosTimeConstructor == 0) {
        printf("LSA: Couldn't find KerberosTime constructor\n");
        return JNI_ERR;
    }
    if (native_debug) {
        printf("LSA: Found KerberosTime constructor\n");
    }

    // load the setRealm method in PrincipalName
    setRealmMethod = (*env)->GetMethodID(env, principalNameClass,
                                    "setRealm", "(Ljava/lang/String;)V");
    if (setRealmMethod == 0) {
        printf("LSA: Couldn't find setRealm in PrincipalName\n");
        return JNI_ERR;
    }

    if (native_debug) {
        printf("LSA: Finished OnLoad processing\n");
    }

    return JNI_VERSION_1_2;
}

/*
 * Class:     sun_security_jgss_KrbCreds
 * Method:    JNI_OnUnload
 */

JNIEXPORT void JNICALL JNI_OnUnload(
        JavaVM  *jvm,
        void    *reserved) {

    JNIEnv *env;

    if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
        return; /* Nothing else we can do */
    }

    if (ticketClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,ticketClass);
    }
    if (derValueClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,derValueClass);
    }
    if (principalNameClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,principalNameClass);
    }
    if (encryptionKeyClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass);
    }
    if (ticketFlagsClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass);
    }
    if (kerberosTimeClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass);
    }
    if (javaLangStringClass != NULL) {
        (*env)->DeleteWeakGlobalRef(env,javaLangStringClass);
    }

    return;
}

/*
 * Class:     sun_security_krb5_Credentials
 * Method:    acquireDefaultNativeCreds
 * Signature: ()Lsun/security/krb5/Credentials;
 */
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds(
        JNIEnv *env,
        jclass krbcredsClass) {

    KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
    PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL;
    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
    NTSTATUS Status, SubStatus;
    ULONG requestSize = 0;
    ULONG responseSize = 0;
    ULONG rspSize = 0;
    HANDLE LogonHandle = NULL;
    ULONG PackageId;
    jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
    jobject ticketFlags, startTime, endTime, krbCreds = NULL;
    jobject authTime, renewTillTime, hostAddresses = NULL;
    KERB_EXTERNAL_TICKET *msticket;
    int ignore_cache = 0;
    FILETIME Now, EndTime, LocalEndTime;

    while (TRUE) {

        if (krbcredsConstructor == 0) {
            krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
                    "(Lsun/security/krb5/internal/Ticket;"
                    "Lsun/security/krb5/PrincipalName;"
                    "Lsun/security/krb5/PrincipalName;"
                    "Lsun/security/krb5/EncryptionKey;"
                    "Lsun/security/krb5/internal/TicketFlags;"
                    "Lsun/security/krb5/internal/KerberosTime;"
                    "Lsun/security/krb5/internal/KerberosTime;"
                    "Lsun/security/krb5/internal/KerberosTime;"
                    "Lsun/security/krb5/internal/KerberosTime;"
                    "Lsun/security/krb5/internal/HostAddresses;)V");
            if (krbcredsConstructor == 0) {
                printf("LSA: Couldn't find sun.security.krb5.Credentials constructor\n");
                break;
            }
        }

        if (native_debug) {
            printf("LSA: Found KrbCreds constructor\n");
        }

        //
        // Get the logon handle and package ID from the
        // Kerberos package
        //
        if (!PackageConnectLookup(&LogonHandle, &PackageId))
            break;

        if (native_debug) {
            printf("LSA: Got handle to Kerberos package\n");
        }

        // Get the MS TGT from cache
        CacheRequest.MessageType = KerbRetrieveTicketMessage;
        CacheRequest.LogonId.LowPart = 0;
        CacheRequest.LogonId.HighPart = 0;

        Status = LsaCallAuthenticationPackage(
                        LogonHandle,
                        PackageId,
                        &CacheRequest,
                        sizeof(CacheRequest),
                        &TktCacheResponse,
                        &rspSize,
                        &SubStatus
                        );

        if (native_debug) {
            printf("LSA: Response size is %d\n", rspSize);
        }

        if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
            if (!LSA_SUCCESS(Status)) {
                ShowNTError("LsaCallAuthenticationPackage", Status);
            } else {
                ShowNTError("Protocol status", SubStatus);
            }
            break;
        }

        // got the native MS TGT
        msticket = &(TktCacheResponse->Ticket);

        // check TGT validity
        switch (msticket->SessionKey.KeyType) {
            case KERB_ETYPE_DES_CBC_CRC:
            case KERB_ETYPE_DES_CBC_MD5:
            case KERB_ETYPE_NULL:
            case KERB_ETYPE_RC4_HMAC_NT:
                GetSystemTimeAsFileTime(&Now);
                EndTime.dwLowDateTime = msticket->EndTime.LowPart;
                EndTime.dwHighDateTime = msticket->EndTime.HighPart;
                FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
                if (CompareFileTime(&Now, &LocalEndTime) >= 0) {
                    ignore_cache = 1;
                }
                if (msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) {
                    ignore_cache = 1;
                }
                break;
            case KERB_ETYPE_RC4_MD4:
            default:
                // not supported
                ignore_cache = 1;
                break;
        }

        if (ignore_cache) {
            if (native_debug) {
                printf("LSA: MS TGT in cache is invalid/not supported; request new ticket\n");
            }

            // use domain to request Ticket
            Status = ConstructTicketRequest(msticket->TargetDomainName,
                                &pTicketRequest, &requestSize);
            if (!LSA_SUCCESS(Status)) {
                ShowNTError("ConstructTicketRequest status", Status);
                break;
            }

            pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
            pTicketRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5;
            pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;

            Status = LsaCallAuthenticationPackage(
                        LogonHandle,
                        PackageId,
                        pTicketRequest,
                        requestSize,
                        &pTicketResponse,
                        &responseSize,
                        &SubStatus
                        );

            if (native_debug) {
                printf("LSA: Response size is %d\n", responseSize);
            }

            if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
                if (!LSA_SUCCESS(Status)) {
                    ShowNTError("LsaCallAuthenticationPackage", Status);
                } else {
                    ShowNTError("Protocol status", SubStatus);
                }
                break;
            }

            // got the native MS Kerberos TGT
            msticket = &(pTicketResponse->Ticket);
        }

        /*

        typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
            KERB_EXTERNAL_TICKET Ticket;
        } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;

        typedef struct _KERB_EXTERNAL_TICKET {
            PKERB_EXTERNAL_NAME ServiceName;
            PKERB_EXTERNAL_NAME TargetName;
            PKERB_EXTERNAL_NAME ClientName;
            UNICODE_STRING DomainName;
            UNICODE_STRING TargetDomainName;
            UNICODE_STRING AltTargetDomainName;
            KERB_CRYPTO_KEY SessionKey;
            ULONG TicketFlags;
            ULONG Flags;
            LARGE_INTEGER KeyExpirationTime;
            LARGE_INTEGER StartTime;
            LARGE_INTEGER EndTime;
            LARGE_INTEGER RenewUntil;
            LARGE_INTEGER TimeSkew;
            ULONG EncodedTicketSize;
            PUCHAR EncodedTicket; <========== Here's the good stuff
        } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;

        typedef struct _KERB_EXTERNAL_NAME {
            SHORT NameType;
            USHORT NameCount;
            UNICODE_STRING Names[ANYSIZE_ARRAY];
        } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME;

        typedef struct _LSA_UNICODE_STRING {
            USHORT Length;
            USHORT MaximumLength;
            PWSTR  Buffer;
        } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;

        typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;

        typedef struct KERB_CRYPTO_KEY {
            LONG KeyType;
            ULONG Length;
            PUCHAR Value;
        } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY;

        */
        // Build a com.sun.security.krb5.Ticket
        ticket = BuildTicket(env, msticket->EncodedTicket,
                                msticket->EncodedTicketSize);
        if (ticket == NULL) {
            break;
        }
        // OK, have a Ticket, now need to get the client name
        clientPrincipal = BuildPrincipal(env, msticket->ClientName,
                                msticket->TargetDomainName); // mdu
        if (clientPrincipal == NULL) {
            break;
        }

        // and the "name" of tgt
        targetPrincipal = BuildPrincipal(env, msticket->ServiceName,
                        msticket->DomainName);
        if (targetPrincipal == NULL) {
            break;
        }

        // Get the encryption key
        encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey));
        if (encryptionKey == NULL) {
            break;
        }

        // and the ticket flags
        ticketFlags = BuildTicketFlags(env, &(msticket->TicketFlags));
        if (ticketFlags == NULL) {
            break;
        }

        // Get the start time
        startTime = BuildKerberosTime(env, &(msticket->StartTime));
        if (startTime == NULL) {
            break;
        }

        /*
         * mdu: No point storing the eky expiration time in the auth
         * time field. Set it to be same as startTime. Looks like
         * windows does not have post-dated tickets.
         */
        authTime = startTime;

        // and the end time
        endTime = BuildKerberosTime(env, &(msticket->EndTime));
        if (endTime == NULL) {
            break;
        }

        // Get the renew till time
        renewTillTime = BuildKerberosTime(env, &(msticket->RenewUntil));
        if (renewTillTime == NULL) {
            break;
        }

        // and now go build a KrbCreds object
        krbCreds = (*env)->NewObject(
                env,
                krbcredsClass,
                krbcredsConstructor,
                ticket,
                clientPrincipal,
                targetPrincipal,
                encryptionKey,
                ticketFlags,
                authTime, // mdu
                startTime,
                endTime,
                renewTillTime, //mdu
                hostAddresses);

        break;
    } // end of WHILE

    // clean up resources
    if (TktCacheResponse != NULL) {
        LsaFreeReturnBuffer(TktCacheResponse);
    }
    if (pTicketRequest) {
        LocalFree(pTicketRequest);
    }
    if (pTicketResponse != NULL) {
        LsaFreeReturnBuffer(pTicketResponse);
    }

    return krbCreds;
}

static NTSTATUS
ConstructTicketRequest(UNICODE_STRING DomainName,
                PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize)
{
    NTSTATUS Status;
    UNICODE_STRING TargetPrefix;
    USHORT TargetSize;
    ULONG RequestSize;
    ULONG Length;
    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;

    *outRequest = NULL;
    *outSize = 0;

    //
    // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
    // can easily concatenate it later.
    //

    TargetPrefix.Buffer = L"krbtgt/";
    Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
    TargetPrefix.Length = (USHORT)Length;
    TargetPrefix.MaximumLength = TargetPrefix.Length;

    //
    // We will need to concatenate the "krbtgt/" prefix and the
    // Logon Session's DnsDomainName into our request's target name.
    //
    // Therefore, first compute the necessary buffer size for that.
    //
    // Note that we might theoretically have integer overflow.
    //

    TargetSize = TargetPrefix.Length + DomainName.Length;

    //
    // The ticket request buffer needs to be a single buffer.  That buffer
    // needs to include the buffer for the target name.
    //

    RequestSize = sizeof (*pTicketRequest) + TargetSize;

    //
    // Allocate the request buffer and make sure it's zero-filled.
    //

    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
                    LocalAlloc(LMEM_ZEROINIT, RequestSize);
    if (!pTicketRequest)
        return GetLastError();

    //
    // Concatenate the target prefix with the previous reponse's
    // target domain.
    //

    pTicketRequest->TargetName.Length = 0;
    pTicketRequest->TargetName.MaximumLength = TargetSize;
    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
    Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
                                    TargetPrefix,
                                    DomainName);
    *outRequest = pTicketRequest;
    *outSize    = RequestSize;
    return Status;
}

DWORD
ConcatenateUnicodeStrings(
    UNICODE_STRING *pTarget,
    UNICODE_STRING Source1,
    UNICODE_STRING Source2
    )
{
    //
    // The buffers for Source1 and Source2 cannot overlap pTarget's
    // buffer.  Source1.Length + Source2.Length must be <= 0xFFFF,
    // otherwise we overflow...
    //

    USHORT TotalSize = Source1.Length + Source2.Length;
    PBYTE buffer = (PBYTE) pTarget->Buffer;

    if (TotalSize > pTarget->MaximumLength)
        return ERROR_INSUFFICIENT_BUFFER;

    pTarget->Length = TotalSize;
    memcpy(buffer, Source1.Buffer, Source1.Length);
    memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
    return ERROR_SUCCESS;
}

BOOL
PackageConnectLookup(
    HANDLE *pLogonHandle,
    ULONG *pPackageId
    )
{
    LSA_STRING Name;
    NTSTATUS Status;

    Status = LsaConnectUntrusted(
                pLogonHandle
                );

    if (!LSA_SUCCESS(Status))
    {
        ShowNTError("LsaConnectUntrusted", Status);
        return FALSE;
    }

    Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
    Name.Length = (USHORT)strlen(Name.Buffer);
    Name.MaximumLength = Name.Length + 1;

    Status = LsaLookupAuthenticationPackage(
                *pLogonHandle,
                &Name,
                pPackageId
                );

    if (!LSA_SUCCESS(Status))
    {
        ShowNTError("LsaLookupAuthenticationPackage", Status);
        return FALSE;
    }

    return TRUE;

}

VOID
ShowLastError(
        LPSTR szAPI,
        DWORD dwError
        )
{
    #define MAX_MSG_SIZE 256

    static WCHAR szMsgBuf[MAX_MSG_SIZE];
    DWORD dwRes;

    if (native_debug) {
        printf("LSA: Error calling function %s: %lu\n", szAPI, dwError);
    }

    dwRes = FormatMessage (
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            dwError,
            0,
            szMsgBuf,
            MAX_MSG_SIZE,
            NULL);
    if (native_debug) {
        if (0 == dwRes) {
            printf("LSA: FormatMessage failed with %d\n", GetLastError());
            // ExitProcess(EXIT_FAILURE);
        } else {
            printf("LSA: %S",szMsgBuf);
        }
    }
}

VOID
ShowNTError(
        LPSTR szAPI,
        NTSTATUS Status
        )
{
    //
    // Convert the NTSTATUS to Winerror. Then call ShowLastError().
    //
    ShowLastError(szAPI, LsaNtStatusToWinError(Status));
}

VOID
InitUnicodeString(
        PUNICODE_STRING DestinationString,
    PCWSTR SourceString OPTIONAL
    )
{
    ULONG Length;

    DestinationString->Buffer = (PWSTR)SourceString;
    if (SourceString != NULL) {
        Length = (ULONG)wcslen( SourceString ) * sizeof( WCHAR );
        DestinationString->Length = (USHORT)Length;
        DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL));
    }
    else {
        DestinationString->MaximumLength = 0;
        DestinationString->Length = 0;
    }
}

jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize) {

    /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket.
     * But before we can do that, we need to make a byte array out of the ET.
     */

    jobject derValue, ticket;
    jbyteArray ary;

    ary = (*env)->NewByteArray(env,encodedTicketSize);
    if ((*env)->ExceptionOccurred(env)) {
        return (jobject) NULL;
    }

    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize,
                                    (jbyte *)encodedTicket);
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->DeleteLocalRef(env, ary);
        return (jobject) NULL;
    }

    derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary);
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->DeleteLocalRef(env, ary);
        return (jobject) NULL;
    }

    (*env)->DeleteLocalRef(env, ary);
    ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue);
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->DeleteLocalRef(env, derValue);
        return (jobject) NULL;
    }
    (*env)->DeleteLocalRef(env, derValue);
    return ticket;
}

// mdu
jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName,
                                UNICODE_STRING domainName) {

    /*
     * To build the Principal, we need to get the names out of
     * this goofy MS structure
     */
    jobject principal = NULL;
    jobject realmStr = NULL;
    jobjectArray stringArray;
    jstring tempString;
    int nameCount,i;
    PUNICODE_STRING scanner;
    WCHAR *realm;
    ULONG realmLen;

    realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
            ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL)));
    wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR));

    if (native_debug) {
        printf("LSA: Principal domain is %S\n", realm);
        printf("LSA: Name type is %x\n", principalName->NameType);
        printf("LSA: Name count is %x\n", principalName->NameCount);
    }

    nameCount = principalName->NameCount;
    stringArray = (*env)->NewObjectArray(env, nameCount,
                            javaLangStringClass, NULL);
    if (stringArray == NULL) {
        if (native_debug) {
            printf("LSA: Can't allocate String array for Principal\n");
        }
        LocalFree(realm);
        return principal;
    }

    for (i=0; i<nameCount; i++) {
        // get the principal name
        scanner = &(principalName->Names[i]);

        // OK, got a Char array, so construct a String
        tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer,
                            scanner->Length/sizeof(WCHAR));
        // Set the String into the StringArray
        (*env)->SetObjectArrayElement(env, stringArray, i, tempString);

        // Do I have to worry about storage reclamation here?
    }
    principal = (*env)->NewObject(env, principalNameClass,
                    principalNameConstructor, stringArray);

    // now set the realm in the principal
    realmLen = (ULONG)wcslen((PWCHAR)realm);
    realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen);
    (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr);

    // free local resources
    LocalFree(realm);

    return principal;
}

jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) {
    // First, need to build a byte array
    jbyteArray ary;
    jobject encryptionKey = NULL;
    unsigned int i;

    for (i=0; i<cryptoKey->Length; i++) {
        if (cryptoKey->Value[i]) break;
    }
    if (i == cryptoKey->Length) {
        if (native_debug) {
            printf("LSA: Session key all zero. Stop.\n");
        }
        return NULL;
    }

    ary = (*env)->NewByteArray(env,cryptoKey->Length);
    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
                                    (jbyte *)cryptoKey->Value);
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->DeleteLocalRef(env, ary);
    } else {
        encryptionKey = (*env)->NewObject(env, encryptionKeyClass,
                encryptionKeyConstructor, cryptoKey->KeyType, ary);
    }

    return encryptionKey;
}

jobject BuildTicketFlags(JNIEnv *env, PULONG flags) {
    jobject ticketFlags = NULL;
    jbyteArray ary;
    /*
     * mdu: Convert the bytes to nework byte order before copying
     * them to a Java byte array.
     */
    ULONG nlflags = htonl(*flags);

    ary = (*env)->NewByteArray(env, sizeof(*flags));
    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
                                    (jbyte *)&nlflags);
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->DeleteLocalRef(env, ary);
    } else {
        ticketFlags = (*env)->NewObject(env, ticketFlagsClass,
                ticketFlagsConstructor, sizeof(*flags)*8, ary);
    }

    return ticketFlags;
}

jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) {
    jobject kerberosTime = NULL;
    jstring stringTime = NULL;
    SYSTEMTIME systemTime;
    WCHAR timeString[16];
    WCHAR month[3];
    WCHAR day[3];
    WCHAR hour[3];
    WCHAR minute[3];
    WCHAR second[3];

    if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) {
        // XXX Cannot use %02.2ld, because the leading 0 is ignored for integers.
        // So, print them to strings, and then print them to the master string with a
        // format pattern that makes it two digits and prefix with a 0 if necessary.
        swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth);
        swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay);
        swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour);
        swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute);
        swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond);
        swprintf( (wchar_t *)timeString,
                L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ",
                systemTime.wYear,
                month,
                day,
                hour,
                minute,
                second );
        if (native_debug) {
            printf("LSA: %S\n", (wchar_t *)timeString);
        }
        stringTime = (*env)->NewString(env, timeString,
                (sizeof(timeString)/sizeof(WCHAR))-1);
        if (stringTime != NULL) { // everything's OK so far
            kerberosTime = (*env)->NewObject(env, kerberosTimeClass,
                    kerberosTimeConstructor, stringTime);
        }
    }
    return kerberosTime;
}
