1 #include <string.h>
2 #include "v2client.h"
3 #include "credentials.h"
4 #include "sasl.h"
5 #include "sasl_internal.h"
6 
setup(int count,struct cvm_credential * creds,const char * account,const char * domain)7 static int setup(int count,
8 		 struct cvm_credential* creds,
9 		 const char* account,
10 		 const char* domain)
11 {
12   memset(creds, 0, count * sizeof creds[0]);
13   creds[0].type = CVM_CRED_ACCOUNT;
14   if (!str_copys(&creds[0].value, account))
15     return 0;
16   if (domain == 0)
17     domain = "";
18   creds[1].type = CVM_CRED_DOMAIN;
19   if (!str_copys(&creds[1].value, domain))
20     return 0;
21   return cvm_client_split_account(&creds[0].value, &creds[1].value);
22 }
23 
free_creds(int count,struct cvm_credential * creds)24 static void free_creds(int count, struct cvm_credential* creds)
25 {
26   while (count > 1)
27     str_free(&creds[--count].value);
28 }
29 
authenticate_free(const char * cvm,int count,struct cvm_credential * creds)30 static int authenticate_free(const char* cvm,
31 			     int count, struct cvm_credential* creds)
32 {
33   int result;
34   result = cvm_client_authenticate(cvm, count, creds);
35   free_creds(count, creds);
36   return result;
37 }
38 
sasl_authenticate_plain(struct sasl_state * ss,const char * account,const char * password)39 int sasl_authenticate_plain(struct sasl_state* ss,
40 			    const char* account, const char* password)
41 {
42   struct cvm_credential creds[3];
43   if (!setup(3, creds, account, ss->domain))
44     return SASL_TEMP_FAIL;
45   creds[2].type = CVM_CRED_PASSWORD;
46   if (!str_copys(&creds[2].value, password))
47     return SASL_TEMP_FAIL;
48   switch (authenticate_free(ss->mech->cvm, 3, creds)) {
49   case 0: return SASL_AUTH_OK;
50   case CVME_PERMFAIL: return SASL_AUTH_FAILED;
51   default: return SASL_TEMP_FAIL;
52   }
53 }
54 
sasl_authenticate_cram(struct sasl_state * ss,const char * account,const char * cram_type,const str * challenge,const str * response)55 int sasl_authenticate_cram(struct sasl_state* ss,
56 			   const char* account, const char* cram_type,
57 			   const str* challenge, const str* response)
58 {
59   struct cvm_credential creds[5];
60   if (!setup(5, creds, account, ss->domain))
61     return SASL_TEMP_FAIL;
62   creds[2].type = CVM_CRED_CHALLENGE;
63   if (!str_copy(&creds[2].value, challenge))
64     return SASL_TEMP_FAIL;
65   creds[3].type = CVM_CRED_RESPONSE;
66   if (!str_copy(&creds[3].value, response))
67     return SASL_TEMP_FAIL;
68   creds[4].type = CVM_CRED_RESPONSE_TYPE;
69   if (!str_copys(&creds[4].value, cram_type))
70     return SASL_TEMP_FAIL;
71   switch (authenticate_free(ss->mech->cvm, 5, creds)) {
72   case 0: return SASL_AUTH_OK;
73   case CVME_PERMFAIL: return SASL_AUTH_FAILED;
74   default: return SASL_TEMP_FAIL;
75   }
76 }
77