github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/gopkg.in/mgo.v2/internal/sasl/sasl_windows.c (about) 1 #include "sasl_windows.h" 2 3 static const LPSTR SSPI_PACKAGE_NAME = "kerberos"; 4 5 SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle *cred_handle, char *username, char *password, char *domain) 6 { 7 SEC_WINNT_AUTH_IDENTITY auth_identity; 8 SECURITY_INTEGER ignored; 9 10 auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; 11 auth_identity.User = (LPSTR) username; 12 auth_identity.UserLength = strlen(username); 13 auth_identity.Password = NULL; 14 auth_identity.PasswordLength = 0; 15 if(password){ 16 auth_identity.Password = (LPSTR) password; 17 auth_identity.PasswordLength = strlen(password); 18 } 19 auth_identity.Domain = (LPSTR) domain; 20 auth_identity.DomainLength = strlen(domain); 21 return call_sspi_acquire_credentials_handle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, cred_handle, &ignored); 22 } 23 24 int sspi_step(CredHandle *cred_handle, int has_context, CtxtHandle *context, PVOID buffer, ULONG buffer_length, PVOID *out_buffer, ULONG *out_buffer_length, char *target) 25 { 26 SecBufferDesc inbuf; 27 SecBuffer in_bufs[1]; 28 SecBufferDesc outbuf; 29 SecBuffer out_bufs[1]; 30 31 if (has_context > 0) { 32 // If we already have a context, we now have data to send. 33 // Put this data in an inbuf. 34 inbuf.ulVersion = SECBUFFER_VERSION; 35 inbuf.cBuffers = 1; 36 inbuf.pBuffers = in_bufs; 37 in_bufs[0].pvBuffer = buffer; 38 in_bufs[0].cbBuffer = buffer_length; 39 in_bufs[0].BufferType = SECBUFFER_TOKEN; 40 } 41 42 outbuf.ulVersion = SECBUFFER_VERSION; 43 outbuf.cBuffers = 1; 44 outbuf.pBuffers = out_bufs; 45 out_bufs[0].pvBuffer = NULL; 46 out_bufs[0].cbBuffer = 0; 47 out_bufs[0].BufferType = SECBUFFER_TOKEN; 48 49 ULONG context_attr = 0; 50 51 int ret = call_sspi_initialize_security_context(cred_handle, 52 has_context > 0 ? context : NULL, 53 (LPSTR) target, 54 ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH, 55 0, 56 SECURITY_NETWORK_DREP, 57 has_context > 0 ? &inbuf : NULL, 58 0, 59 context, 60 &outbuf, 61 &context_attr, 62 NULL); 63 64 *out_buffer = malloc(out_bufs[0].cbBuffer); 65 *out_buffer_length = out_bufs[0].cbBuffer; 66 memcpy(*out_buffer, out_bufs[0].pvBuffer, *out_buffer_length); 67 68 return ret; 69 } 70 71 int sspi_send_client_authz_id(CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *user_plus_realm) 72 { 73 SecPkgContext_Sizes sizes; 74 SECURITY_STATUS status = call_sspi_query_context_attributes(context, SECPKG_ATTR_SIZES, &sizes); 75 76 if (status != SEC_E_OK) { 77 return status; 78 } 79 80 size_t user_plus_realm_length = strlen(user_plus_realm); 81 int msgSize = 4 + user_plus_realm_length; 82 char *msg = malloc((sizes.cbSecurityTrailer + msgSize + sizes.cbBlockSize) * sizeof(char)); 83 msg[sizes.cbSecurityTrailer + 0] = 1; 84 msg[sizes.cbSecurityTrailer + 1] = 0; 85 msg[sizes.cbSecurityTrailer + 2] = 0; 86 msg[sizes.cbSecurityTrailer + 3] = 0; 87 memcpy(&msg[sizes.cbSecurityTrailer + 4], user_plus_realm, user_plus_realm_length); 88 89 SecBuffer wrapBufs[3]; 90 SecBufferDesc wrapBufDesc; 91 wrapBufDesc.cBuffers = 3; 92 wrapBufDesc.pBuffers = wrapBufs; 93 wrapBufDesc.ulVersion = SECBUFFER_VERSION; 94 95 wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; 96 wrapBufs[0].BufferType = SECBUFFER_TOKEN; 97 wrapBufs[0].pvBuffer = msg; 98 99 wrapBufs[1].cbBuffer = msgSize; 100 wrapBufs[1].BufferType = SECBUFFER_DATA; 101 wrapBufs[1].pvBuffer = msg + sizes.cbSecurityTrailer; 102 103 wrapBufs[2].cbBuffer = sizes.cbBlockSize; 104 wrapBufs[2].BufferType = SECBUFFER_PADDING; 105 wrapBufs[2].pvBuffer = msg + sizes.cbSecurityTrailer + msgSize; 106 107 status = call_sspi_encrypt_message(context, SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); 108 if (status != SEC_E_OK) { 109 free(msg); 110 return status; 111 } 112 113 *buffer_length = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; 114 *buffer = malloc(*buffer_length); 115 116 memcpy(*buffer, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); 117 memcpy(*buffer + wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); 118 memcpy(*buffer + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer); 119 120 free(msg); 121 return SEC_E_OK; 122 }