~ubuntu-branches/ubuntu/trusty/psqlodbc/trusty-proposed

« back to all changes in this revision

Viewing changes to sspisvcs.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Berg
  • Date: 2011-04-05 14:48:23 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110405144823-n77supsa1hjj0ik6
Tags: 1:09.00.0200-1
* New upstream release.
* Fix installing {A,W}/usr/lib/odbc.  Closes: #618210.
* Convert to 3.0 (quilt).
* Remove psqlodbc-580878.diff: implemented upstream.
* Remove psqlodbc-585476.diff: was caused by #519006 which is now closed.
* Update description, suggested by Martin Eberhard Schauer.
  Closes: #565611.
* New maintainer.  Closes: #472818.

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
        retry_count = 0;
65
65
        for (ttllen = 0, reqlen = len; reqlen > 0;)
66
66
        {
67
 
                if (0 > (wrtlen = send(sock, (const char *) buf + ttllen, reqlen, 0)))
 
67
                if (0 > (wrtlen = send(sock, (const char *) buf + ttllen, reqlen, SEND_FLAG)))
68
68
                {
69
69
                        int     gerrno = SOCK_ERRNO;
70
70
 
97
97
 
98
98
        for (ttllen = 0, reqlen = len; reqlen > 0;)
99
99
        {
100
 
                if (0 > (rcvlen = recv(sock, (char *) buf + ttllen, reqlen, 0)))
 
100
                if (0 > (rcvlen = recv(sock, (char *) buf + ttllen, reqlen, RECV_FLAG)))
101
101
                {
102
102
                        int     gerrno = SOCK_ERRNO;
103
103
 
122
122
        return ttllen;
123
123
}
124
124
 
125
 
CSTR    SCHANNEL = "sChannel";
126
 
static int DoSchannelNegotiation(SocketClass *, const char *opt);
127
 
int StartupSspiService(SocketClass *self, SSPI_Service svc, const char *opt)
128
 
{
129
 
        CSTR func = "DoServicelNegotiation";
130
 
 
131
 
        switch (svc)
132
 
        {
133
 
                case SchannelService:
134
 
                        return DoSchannelNegotiation(self, opt);
135
 
        }
136
 
 
137
 
        return -1;
138
 
}
139
 
 
140
 
/*
141
 
 *      Stuff for Schannel service
 
125
/*      
 
126
 *      service specific data
142
127
 */
143
 
#include        <schannel.h>
144
 
#pragma comment(lib, "crypt32")
145
 
#define UNI_SCHANNEL TEXT("sChannel")
146
 
#define IO_BUFFER_SIZE  0x10000
147
128
 
 
129
/*      Schannel specific data */
148
130
typedef struct {
149
131
        CredHandle      hCred;
150
132
        CtxtHandle      hCtxt;
155
137
        size_t          ioread;
156
138
} SchannelSpec;
157
139
 
 
140
/*      Kerberos/Negotiate common specific data */
 
141
typedef struct {
 
142
        LPTSTR          svcprinc;
 
143
        CredHandle      hKerbEtcCred;
 
144
        BOOL            ValidCtxt;
 
145
        CtxtHandle      hKerbEtcCtxt;
 
146
} KerberosEtcSpec;
 
147
 
 
148
typedef struct {
 
149
        SchannelSpec    sdata;
 
150
        KerberosEtcSpec kdata;
 
151
} SspiData;
 
152
 
 
153
static int DoSchannelNegotiation(SocketClass *, SspiData *, const void *opt);
 
154
static int DoKerberosNegotiation(SocketClass *, SspiData *, const void *opt);
 
155
static int DoNegotiateNegotiation(SocketClass *, SspiData *, const void *opt);
 
156
static int DoKerberosEtcProcessAuthentication(SocketClass *, const void *opt);
 
157
 
 
158
static SspiData *SspiDataAlloc(SocketClass *self)
 
159
{
 
160
        SspiData        *sspidata;
 
161
 
 
162
        if (sspidata = self->ssd, !sspidata)
 
163
                sspidata = calloc(sizeof(SspiData), 1);
 
164
        return sspidata;
 
165
}
 
166
 
 
167
int StartupSspiService(SocketClass *self, SSPI_Service svc, const void *opt)
 
168
{
 
169
        CSTR func = "DoServicelNegotiation";
 
170
        SspiData        *sspidata;
 
171
 
 
172
        if (NULL == (sspidata = SspiDataAlloc(self)))
 
173
                return -1;
 
174
        switch (svc)
 
175
        {
 
176
                case SchannelService:
 
177
                        return DoSchannelNegotiation(self, sspidata, opt);
 
178
                case KerberosService:
 
179
                        return DoKerberosNegotiation(self, sspidata, opt);
 
180
                case NegotiateService:
 
181
                        return DoNegotiateNegotiation(self, sspidata, opt);
 
182
        }
 
183
 
 
184
        free(sspidata);
 
185
        return -1;
 
186
}
 
187
 
 
188
int ContinueSspiService(SocketClass *self, SSPI_Service svc, const void *opt)
 
189
{
 
190
        CSTR func = "ContinueSspiService";
 
191
 
 
192
        switch (svc)
 
193
        {
 
194
                case KerberosService:
 
195
                case NegotiateService:
 
196
                        return DoKerberosEtcProcessAuthentication(self, opt);
 
197
        }
 
198
 
 
199
        return -1;
 
200
}
 
201
 
 
202
static BOOL format_sspierr(char *errmsg, size_t buflen, SECURITY_STATUS r, const char *cmd, const char *cmd2)
 
203
{
 
204
        BOOL ret = FALSE;
 
205
 
 
206
        if (!cmd2)
 
207
                cmd2 = ""; 
 
208
        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
 
209
                r, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
 
210
                errmsg, (DWORD)buflen, NULL))
 
211
                ret = TRUE;
 
212
        if (ret)
 
213
        {
 
214
                size_t  tlen = strlen(errmsg);
 
215
                errmsg += tlen;
 
216
                buflen -= tlen;
 
217
                snprintf(errmsg, buflen, " in %s:%s", cmd, cmd2);
 
218
        }
 
219
        else
 
220
                snprintf(errmsg, buflen, "%s:%s failed ", cmd, cmd2);
 
221
        return ret;
 
222
}
 
223
 
 
224
static void SSPI_set_error(SocketClass *s, SECURITY_STATUS r, const char *cmd, const char *cmd2)
 
225
{
 
226
        int     gerrno = SOCK_ERRNO;
 
227
        char    emsg[256];
 
228
 
 
229
        format_sspierr(emsg, sizeof(emsg), r, cmd, cmd2);
 
230
        s->errornumber = r;
 
231
        if (NULL != s->_errormsg_)
 
232
                free(s->_errormsg_);
 
233
        if (NULL != emsg)
 
234
                s->_errormsg_ = strdup(emsg);
 
235
        else
 
236
                s->_errormsg_ = NULL;
 
237
        mylog("(%d)%s ERRNO=%d\n", r, emsg, gerrno);
 
238
}
 
239
 
 
240
/*
 
241
 *      Stuff for Schannel service
 
242
 */
 
243
#include        <schannel.h>
 
244
#pragma comment(lib, "crypt32")
 
245
#define UNI_SCHANNEL TEXT("sChannel")
 
246
#define IO_BUFFER_SIZE  0x10000
 
247
 
158
248
static SECURITY_STATUS CreateSchannelCredentials(LPCTSTR, LPSTR, PCredHandle);
159
249
static SECURITY_STATUS PerformSchannelClientHandshake(SOCKET, PCredHandle, LPSTR, CtxtHandle *, SecBuffer *);
160
250
static SECURITY_STATUS SchannelClientHandshakeLoop(SOCKET, PCredHandle, CtxtHandle *, BOOL, SecBuffer *);
162
252
 
163
253
static HCERTSTORE       hMyCertStore = NULL;
164
254
 
165
 
static int DoSchannelNegotiation(SocketClass *self, const char *opt)
 
255
static int DoSchannelNegotiation(SocketClass *self, SspiData *sspidata, const void *opt)
166
256
{
167
257
        CSTR func = "DoSchannelNegotiation";
 
258
        SECURITY_STATUS r = SEC_E_OK;
 
259
        const char      *cmd = NULL;
168
260
        SecBuffer       ExtraData;
169
261
        BOOL            ret = 0, cCreds = FALSE, cCtxt = FALSE;
170
 
        SchannelSpec    *ssd = NULL;
 
262
        SchannelSpec    *ssd = &(sspidata->sdata);
171
263
 
172
 
        if (NULL == (ssd = calloc(sizeof(SchannelSpec), 1)))
173
 
        {
174
 
                return 0;
175
 
        }
176
 
        if (SEC_E_OK != CreateSchannelCredentials(NULL, NULL, &ssd->hCred))
177
 
        {
178
 
                mylog("%s:CreateSchannel failed\n", func);
 
264
        if (SEC_E_OK != (r = CreateSchannelCredentials(NULL, NULL, &ssd->hCred)))
 
265
        {
 
266
                cmd = "CreateSchannelCredentials";
 
267
                mylog("%s:%s failed\n", func, cmd);
179
268
                goto cleanup;
180
269
        }
181
270
        cCreds = TRUE;
182
 
        if (SEC_E_OK != PerformSchannelClientHandshake(self->socket, &ssd->hCred, NULL, &ssd->hCtxt, &ExtraData))
 
271
        if (SEC_E_OK != (r = PerformSchannelClientHandshake(self->socket, &ssd->hCred, NULL, &ssd->hCtxt, &ExtraData)))
183
272
        {
184
 
                mylog("%s:PerformSchannelClientHandshake failed\n", func);
 
273
                cmd = "PerformSchannelClientHandshake";
 
274
                mylog("%s:%s failed\n", func, cmd);
185
275
                goto cleanup;
186
276
        }
187
277
        cCtxt = TRUE;
198
288
        if (ret)
199
289
        {
200
290
                self->sspisvcs |= SchannelService;
201
 
                self->ssd = ssd;
 
291
                self->ssd = sspidata;
202
292
        }
203
293
        else
204
294
        {
 
295
                SSPI_set_error(self, r, __FUNCTION__, cmd); 
205
296
                if (cCreds)
206
297
                        FreeCredentialHandle(&ssd->hCred);
207
298
                if (cCtxt)
208
299
                        DeleteSecurityContext(&ssd->hCtxt);
209
300
                if (ssd->iobuf)
210
301
                        free(ssd->iobuf);
211
 
                free(ssd);
 
302
                if (!self->ssd)
 
303
                        free(sspidata);
212
304
        }
213
305
        return ret;
214
306
}
303
395
         */
304
396
 
305
397
        Status = AcquireCredentialsHandle(
306
 
                        NULL,                   /* Name of principal */    
307
 
                        UNI_SCHANNEL,           /* Name of package */
308
 
                        SECPKG_CRED_OUTBOUND,   /* Flags indicating use */
309
 
                        NULL,                   /* Pointer to logon ID */
310
 
                        &SchannelCred,          /* Package specific data */
311
 
                        NULL,                   /* Pointer to GetKey() func */
312
 
                        NULL,                   /* Value to pass to GetKey() */
313
 
                        phCreds,                /* (out) Cred Handle */
314
 
                        &tsExpiry);             /* (out) Lifetime (optional) */
 
398
                        NULL,                   /* Name of principal */    
 
399
                        UNI_SCHANNEL,           /* Name of package */
 
400
                        SECPKG_CRED_OUTBOUND,   /* Flags indicating use */
 
401
                        NULL,                   /* Pointer to logon ID */
 
402
                        &SchannelCred,          /* Package specific data */
 
403
                        NULL,                   /* Pointer to GetKey() func */
 
404
                        NULL,                   /* Value to pass to GetKey() */
 
405
                        phCreds,                /* (out) Cred Handle */
 
406
                        &tsExpiry);             /* (out) Lifetime (optional) */
315
407
        if (Status != SEC_E_OK)
316
408
        {
317
409
                mylog("**** Error 0x%p returned by AcquireCredentialsHandle\n", Status);
385
477
 
386
478
        if (scRet != SEC_I_CONTINUE_NEEDED)
387
479
        {
388
 
                mylog("**** Error %d returned by InitializeSecurityContext (1)\n", scRet);
 
480
                mylog("**** Error %x returned by InitializeSecurityContext (1)\n", scRet);
389
481
                return scRet;
390
482
        }
391
483
 
397
489
                                OutBuffers[0].cbBuffer);
398
490
                if (cbData <= 0)
399
491
                {
400
 
                        mylog("**** Error %d sending data to server (1)\n", SOCK_ERRNO);
 
492
                        mylog("**** Error %x sending data to server\n", SOCK_ERRNO);
401
493
                        FreeContextBuffer(OutBuffers[0].pvBuffer);
402
494
                        DeleteSecurityContext(phContext);
403
495
                        return SEC_E_INTERNAL_ERROR;
478
570
                                cbData = recv(Socket, 
479
571
                                                IoBuffer + cbIoBuffer, 
480
572
                                                IO_BUFFER_SIZE - cbIoBuffer, 
481
 
                                                0);
 
573
                                                RECV_FLAG);
482
574
                                if (cbData == SOCKET_ERROR)
483
575
                                {
484
576
                                        int     gerrno = SOCK_ERRNO;
496
588
                                                                continue;
497
589
                                                default:
498
590
                                                        scRet = SEC_E_INTERNAL_ERROR;
 
591
                                                        SOCK_ERRNO_SET(gerrno);
499
592
                                                        break;
500
593
                                        }
501
594
                                        break;
830
923
        }
831
924
}
832
925
 
 
926
/*
 
927
 *      Stuff for Kerberos etc service
 
928
 */
 
929
#define UNI_KERBEROS TEXT("Kerberos")
 
930
#define UNI_NEGOTIATE TEXT("Negotiate")
 
931
#define IO_BUFFER_SIZE  0x10000
 
932
 
 
933
 
 
934
static SECURITY_STATUS CreateKerberosEtcCredentials(LPCTSTR, SEC_CHAR *, LPCTSTR, PCredHandle);
 
935
static SECURITY_STATUS PerformKerberosEtcClientHandshake(SocketClass *, KerberosEtcSpec *ssd, size_t);
 
936
 
 
937
static int DoKerberosNegotiation(SocketClass *self, SspiData *sspidata, const void *opt)
 
938
{
 
939
        CSTR func = "DoKerberosNegotiation";
 
940
        SECURITY_STATUS r = SEC_E_OK;
 
941
        const char *    cmd = NULL;
 
942
        BOOL            ret = 0;
 
943
        KerberosEtcSpec *ssd = &(sspidata->kdata);
 
944
 
 
945
mylog("!!! %s in\n", __FUNCTION__);
 
946
        if (SEC_E_OK != (r = CreateKerberosEtcCredentials(NULL, UNI_KERBEROS, (LPCTSTR) opt, &ssd->hKerbEtcCred)))
 
947
        {
 
948
                cmd = "CreateKerberosCredentials";
 
949
                mylog("%s:%s failed\n", func, cmd);
 
950
                SSPI_set_error(self, r, __FUNCTION__, cmd); 
 
951
                return 0;
 
952
        }
 
953
mylog("!!! CreateKerberosCredentials passed\n");
 
954
 
 
955
        ssd->svcprinc = (LPTSTR) opt;
 
956
        self->sspisvcs |= KerberosService;
 
957
        self->ssd = sspidata;
 
958
        return DoKerberosEtcProcessAuthentication(self, NULL);
 
959
}
 
960
 
 
961
static int DoNegotiateNegotiation(SocketClass *self, SspiData *sspidata, const void *opt)
 
962
{
 
963
        CSTR func = "DoNegotiateNegotiation";
 
964
        SECURITY_STATUS r = SEC_E_OK;
 
965
        const char *    cmd = NULL;
 
966
        BOOL            ret = 0;
 
967
        KerberosEtcSpec *ssd = &(sspidata->kdata);
 
968
 
 
969
mylog("!!! %s in\n", __FUNCTION__);
 
970
        if (SEC_E_OK != (r = CreateKerberosEtcCredentials(NULL, UNI_NEGOTIATE, (LPCTSTR) opt, &ssd->hKerbEtcCred)))
 
971
        {
 
972
                cmd = "CreateNegotiateCredentials";
 
973
                mylog("%s:%s failed\n", func, cmd);
 
974
                SSPI_set_error(self, r, __FUNCTION__, cmd); 
 
975
                return 0;
 
976
        }
 
977
mylog("!!! CreateNegotiateCredentials passed\n");
 
978
 
 
979
        ssd->svcprinc = (LPTSTR) opt;
 
980
        self->sspisvcs |= NegotiateService;
 
981
        self->ssd = sspidata;
 
982
        return DoKerberosEtcProcessAuthentication(self, NULL);
 
983
}
 
984
 
 
985
static int DoKerberosEtcProcessAuthentication(SocketClass *self, const void *opt)
 
986
{
 
987
        CSTR func = "DoKerberosEtcProcessAuthentication";
 
988
        SECURITY_STATUS r = SEC_E_OK;
 
989
        const char *    cmd = NULL;
 
990
        BOOL            ret = 0, cCtxt = FALSE;
 
991
        KerberosEtcSpec *ssd;
 
992
 
 
993
mylog("!!! %s in\n", __FUNCTION__);
 
994
        ssd = &(((SspiData *)(self->ssd))->kdata);
 
995
        if (SEC_E_OK != (r = PerformKerberosEtcClientHandshake(self, ssd, (size_t) opt)))
 
996
        {
 
997
                cmd = "PerformKerberosEtcClientHandshake";
 
998
                mylog("%s:%s failed\n", func, cmd);
 
999
                goto cleanup;
 
1000
        }
 
1001
mylog("!!! PerformKerberosEtcClientHandshake passed\n");
 
1002
        cCtxt = TRUE;
 
1003
        ret = TRUE;
 
1004
cleanup:
 
1005
        if (!ret)
 
1006
        {
 
1007
                SSPI_set_error(self, r, __FUNCTION__, cmd); 
 
1008
                FreeCredentialHandle(&ssd->hKerbEtcCred);
 
1009
                if (cCtxt)
 
1010
                {
 
1011
                        DeleteSecurityContext(&ssd->hKerbEtcCtxt);
 
1012
                }
 
1013
                self->sspisvcs &= (~(KerberosService | NegotiateService));
 
1014
        }
 
1015
        return ret;
 
1016
}
 
1017
 
 
1018
static
 
1019
SECURITY_STATUS
 
1020
CreateKerberosEtcCredentials(
 
1021
        LPCTSTR opt,            /* in */
 
1022
        SEC_CHAR *packname,     /* in */
 
1023
        LPCTSTR pszUserName,    /* in */
 
1024
        PCredHandle phCreds)    /* out */
 
1025
{
 
1026
        TimeStamp       tsExpiry;
 
1027
        SECURITY_STATUS Status;
 
1028
 
 
1029
        /*
 
1030
         * Create an SSPI credential.
 
1031
         */
 
1032
 
 
1033
        Status = AcquireCredentialsHandle(
 
1034
                        NULL,                   /* Name of principal */    
 
1035
                        packname,               /* Name of package */
 
1036
                        SECPKG_CRED_OUTBOUND,   /* Flags indicating use */
 
1037
                        NULL,                   /* Pointer to logon ID */
 
1038
                        NULL,                   /* Package specific data */
 
1039
                        NULL,                   /* Pointer to GetKey() func */
 
1040
                        NULL,                   /* Value to pass to GetKey() */
 
1041
                        phCreds,                /* (out) Cred Handle */
 
1042
                        &tsExpiry);             /* (out) Lifetime (optional) */
 
1043
        if (Status != SEC_E_OK)
 
1044
        {
 
1045
                mylog("**** Error 0x%p returned by AcquireCredentialsHandle\n", Status);
 
1046
                goto cleanup;
 
1047
        }
 
1048
 
 
1049
cleanup:
 
1050
 
 
1051
    return Status;
 
1052
}
 
1053
 
 
1054
static
 
1055
SECURITY_STATUS
 
1056
PerformKerberosEtcClientHandshake(
 
1057
        SocketClass     *sock,          /* in */
 
1058
        KerberosEtcSpec *ssd,           /* i-o */
 
1059
        size_t          inlen)
 
1060
{
 
1061
        SecBufferDesc   InBuffer;
 
1062
        SecBuffer       InBuffers[1];
 
1063
        SecBufferDesc   OutBuffer;
 
1064
        SecBuffer       OutBuffers[1];
 
1065
        DWORD           dwSSPIFlags;
 
1066
        DWORD           dwSSPIOutFlags;
 
1067
        TimeStamp       tsExpiry;
 
1068
        SECURITY_STATUS scRet;
 
1069
        CtxtHandle      hContext;
 
1070
        PBYTE           inbuf = NULL;
 
1071
 
 
1072
mylog("!!! inlen=%u svcprinc=%s\n", inlen, ssd->svcprinc); 
 
1073
        if (ssd->ValidCtxt && inlen > 0)
 
1074
        {
 
1075
                if (NULL == (inbuf = malloc(inlen + 1)))
 
1076
                {
 
1077
                        return SEC_E_INTERNAL_ERROR;
 
1078
                }
 
1079
                SOCK_get_n_char(sock, inbuf, inlen);
 
1080
                if (SOCK_get_errcode(sock) != 0)
 
1081
                {
 
1082
                        mylog("**** Error %d receiving data from server (1)\n", SOCK_ERRNO);
 
1083
                        free(inbuf);
 
1084
                        return SEC_E_INTERNAL_ERROR;
 
1085
                }
 
1086
 
 
1087
                InBuffer.ulVersion = SECBUFFER_VERSION;
 
1088
                InBuffer.cBuffers = 1;
 
1089
                InBuffer.pBuffers = InBuffers;
 
1090
                InBuffers[0].pvBuffer = inbuf; 
 
1091
                InBuffers[0].cbBuffer = inlen; 
 
1092
                InBuffers[0].BufferType = SECBUFFER_TOKEN; 
 
1093
        }
 
1094
 
 
1095
        dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT   |
 
1096
                        ISC_REQ_REPLAY_DETECT   |
 
1097
                        ISC_REQ_CONFIDENTIALITY |
 
1098
                        ISC_RET_EXTENDED_ERROR  |
 
1099
                        ISC_REQ_ALLOCATE_MEMORY |
 
1100
                        ISC_REQ_STREAM;
 
1101
 
 
1102
        /*
 
1103
         *  Initiate a ClientHello message and generate a token.
 
1104
         */
 
1105
 
 
1106
        OutBuffers[0].pvBuffer  = NULL;
 
1107
        OutBuffers[0].BufferType = SECBUFFER_TOKEN;
 
1108
        OutBuffers[0].cbBuffer  = 0;
 
1109
 
 
1110
        OutBuffer.cBuffers = 1;
 
1111
        OutBuffer.pBuffers = OutBuffers;
 
1112
        OutBuffer.ulVersion = SECBUFFER_VERSION;
 
1113
 
 
1114
mylog("!!! before InitializeSecurityContext\n"); 
 
1115
        scRet = InitializeSecurityContext(
 
1116
                                        &ssd->hKerbEtcCred,
 
1117
                                        ssd->ValidCtxt ? &ssd->hKerbEtcCtxt : NULL,
 
1118
                                        ssd->svcprinc,
 
1119
                                        dwSSPIFlags,
 
1120
                                        0,
 
1121
                                        SECURITY_NATIVE_DREP,
 
1122
                                        ssd->ValidCtxt ? &InBuffer : NULL,
 
1123
                                        0,
 
1124
                                        &hContext,
 
1125
                                        &OutBuffer,
 
1126
                                        &dwSSPIOutFlags,
 
1127
                                        &tsExpiry);
 
1128
mylog("!!! %s:InitializeSecurityContext ret=%x\n", __FUNCTION__, scRet); 
 
1129
 
 
1130
        if (inbuf)
 
1131
                free(inbuf);
 
1132
        if (SEC_E_OK != scRet && SEC_I_CONTINUE_NEEDED != scRet)
 
1133
        {
 
1134
                mylog("**** Error %x returned by InitializeSecurityContext\n", scRet);
 
1135
                return scRet;
 
1136
        }
 
1137
        if (!ssd->ValidCtxt)
 
1138
        {
 
1139
                memcpy(&ssd->hKerbEtcCtxt, &hContext, sizeof(CtxtHandle));
 
1140
                ssd->ValidCtxt = TRUE;
 
1141
        }
 
1142
 
 
1143
mylog("!!! cbBuffer=%d pvBuffer=%p\n", OutBuffers[0].cbBuffer, OutBuffers[0].pvBuffer); 
 
1144
        /* Send response to server if there is one. */
 
1145
        if (OutBuffers[0].cbBuffer != 0 && OutBuffers[0].pvBuffer != NULL)
 
1146
        {
 
1147
                int     reslen = OutBuffers[0].cbBuffer;
 
1148
mylog("!!! responding 'p' + int(%d) + %dbytes of data\n", reslen + 4, reslen); 
 
1149
                SOCK_put_char(sock, 'p');
 
1150
                SOCK_put_int(sock, reslen + 4, 4);
 
1151
                SOCK_put_n_char(sock, OutBuffers[0].pvBuffer, reslen);
 
1152
                SOCK_flush_output(sock);
 
1153
                if (SOCK_get_errcode(sock) != 0)
 
1154
                {
 
1155
                        mylog("**** Error %d sending data to server (1)\n", SOCK_ERRNO);
 
1156
                        FreeContextBuffer(OutBuffers[0].pvBuffer);
 
1157
                        return SEC_E_INTERNAL_ERROR;
 
1158
                }
 
1159
 
 
1160
                mylog("%d bytes of handshake data sent\n", OutBuffers[0].cbBuffer);
 
1161
 
 
1162
                /* Free output buffer. */
 
1163
                FreeContextBuffer(OutBuffers[0].pvBuffer);
 
1164
                OutBuffers[0].pvBuffer = NULL;
 
1165
        }
 
1166
 
 
1167
        return SEC_E_OK;
 
1168
        // return KerberosEtcClientHandshakeLoop(Socket, ssd, TRUE, pExtraData);
 
1169
}
 
1170
 
 
1171
 
833
1172
int SSPI_recv(SocketClass *self, void *buffer, int len)
834
1173
{
835
1174
        CSTR func = "SSPI_recv";
847
1186
                DWORD   cbIoBuffer, cbIoBufferLength;
848
1187
 
849
1188
                DWORD   cbData;
850
 
                SchannelSpec *ssd = (SchannelSpec *) self->ssd;
 
1189
                SchannelSpec *ssd = &(((SspiData *)(self->ssd))->sdata);
851
1190
 
852
1191
mylog("buflen=%d,%d ovrlen=%d\n", ssd->iobuflen, ssd->ioread, ssd->ioovrlen);
853
1192
                if (ssd->ioovrlen > 0)
904
1243
                                cbData = recv(self->socket, 
905
1244
                                                pbIoBuffer + cbIoBuffer, 
906
1245
                                                reqlen, 
907
 
                                                0);
 
1246
                                                RECV_FLAG);
908
1247
                                if (cbData == SOCKET_ERROR)
909
1248
                                {
910
1249
                                        int     gerrno = SOCK_ERRNO;
914
1253
                                        {
915
1254
                                                case EINTR:
916
1255
                                                        continue;
917
 
                                                case ECONNRESET:
918
 
                                                        break;
919
1256
                                                case EWOULDBLOCK:
920
1257
                                                        retry_count++;
921
1258
                                                        if (Socket_wait_for_ready(self->socket, FALSE, retry_count) >= 0)
922
1259
                                                                continue;
923
1260
                                                default:
 
1261
                                                        SOCK_ERRNO_SET(gerrno);
924
1262
                                                        scRet = SEC_E_INTERNAL_ERROR;
925
1263
                                                        break;
926
1264
                                        }
1075
1413
                return rtnlen;
1076
1414
        }
1077
1415
        else
1078
 
                return recv(self->socket, (char *) buffer, len, 0);
 
1416
                return recv(self->socket, (char *) buffer, len, RECV_FLAG);
1079
1417
}
1080
1418
 
1081
1419
int SSPI_send(SocketClass *self, const void *buffer, int len)
1091
1429
                LPVOID  lpTrail;
1092
1430
                SecBuffer       sb[4];
1093
1431
                SecBufferDesc   sbd;
1094
 
                SchannelSpec *ssd = (SchannelSpec *) self->ssd;
 
1432
                SchannelSpec *ssd = &(((SspiData *)(self->ssd))->sdata);
1095
1433
 
1096
1434
                QueryContextAttributes(&ssd->hCtxt, SECPKG_ATTR_STREAM_SIZES, &sizes);
1097
1435
                slen = len;
1139
1477
                return slen;
1140
1478
        }
1141
1479
        else
1142
 
                return send(self->socket, (char *) buffer, len, 0);
 
1480
                return send(self->socket, (char *) buffer, len, SEND_FLAG);
1143
1481
}
1144
1482
 
1145
 
void ReleaseSvcSpecData(SocketClass *self)
 
1483
void ReleaseSvcSpecData(SocketClass *self, UInt4 svc)
1146
1484
{
1147
1485
        if (!self->ssd)
1148
1486
                return;
1149
 
        if (0 != (self->sspisvcs & SchannelService))
 
1487
        if (0 != (self->sspisvcs & (svc & SchannelService)))
1150
1488
        {
1151
 
                SchannelSpec *ssd = (SchannelSpec *) self->ssd;
 
1489
                SchannelSpec *ssd = &(((SspiData *)(self->ssd))->sdata);
1152
1490
 
1153
1491
                if (ssd->iobuf)
1154
1492
                {
1164
1502
                DeleteSecurityContext(&ssd->hCtxt);
1165
1503
                self->sspisvcs &= (~SchannelService);
1166
1504
        }
 
1505
        if (0 != (self->sspisvcs & (svc & (KerberosService | NegotiateService))))
 
1506
        {
 
1507
                KerberosEtcSpec *ssd = &(((SspiData *)(self->ssd))->kdata);
 
1508
 
 
1509
                if (ssd->svcprinc)
 
1510
                {
 
1511
                        free(ssd->svcprinc);
 
1512
                        ssd->svcprinc = NULL;
 
1513
                }
 
1514
                FreeCredentialHandle(&ssd->hKerbEtcCred);
 
1515
                if (ssd->ValidCtxt)
 
1516
                {
 
1517
                        DeleteSecurityContext(&ssd->hKerbEtcCtxt);
 
1518
                        ssd->ValidCtxt = FALSE;
 
1519
                }
 
1520
                self->sspisvcs &= (~(KerberosService | NegotiateService));
 
1521
        }
1167
1522
}
1168
1523
#endif /* USE_SSPI */