7 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
8 krb5_mk_chpw_req(context, auth_context, ap_req, passwd, packet)
10 krb5_auth_context auth_context;
18 krb5_replay_data replay;
21 if (ret = krb5_auth_con_setflags(context, auth_context,
22 KRB5_AUTH_CONTEXT_DO_SEQUENCE))
25 clearpw.length = strlen(passwd);
26 clearpw.data = passwd;
28 if (ret = krb5_mk_priv(context, auth_context,
29 &clearpw, &cipherpw, &replay))
32 packet->length = 6 + ap_req->length + cipherpw.length;
33 packet->data = (char *) malloc(packet->length);
34 if (packet->data == NULL)
40 *ptr++ = (packet->length>>8) & 0xff;
41 *ptr++ = packet->length & 0xff;
43 /* version == 0x0001 big-endian */
48 /* ap_req length, big-endian */
50 *ptr++ = (ap_req->length>>8) & 0xff;
51 *ptr++ = ap_req->length & 0xff;
55 memcpy(ptr, ap_req->data, ap_req->length);
56 ptr += ap_req->length;
58 /* krb-priv of password */
60 memcpy(ptr, cipherpw.data, cipherpw.length);
65 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
66 krb5_rd_chpw_rep(context, auth_context, packet, result_code, result_data)
68 krb5_auth_context auth_context;
71 krb5_data *result_data;
76 krb5_ap_rep_enc_part *ap_rep_enc;
78 krb5_data cipherresult;
79 krb5_data clearresult;
81 krb5_replay_data replay;
84 if (packet->length < 4)
85 /* either this, or the server is printing bad messages,
86 or the caller passed in garbage */
87 return(KRB5KRB_AP_ERR_MODIFIED);
93 plen = (*ptr++ & 0xff);
94 plen = (plen<<8) | (*ptr++ & 0xff);
96 if (plen != packet->length)
97 return(KRB5KRB_AP_ERR_MODIFIED);
99 /* verify version number */
101 vno = (*ptr++ & 0xff);
102 vno = (vno<<8) | (*ptr++ & 0xff);
105 return(KRB5KDC_ERR_BAD_PVNO);
107 /* read, check ap-rep length */
109 ap_rep.length = (*ptr++ & 0xff);
110 ap_rep.length = (ap_rep.length<<8) | (*ptr++ & 0xff);
112 if (ptr + ap_rep.length >= packet->data + packet->length)
113 return(KRB5KRB_AP_ERR_MODIFIED);
118 ptr += ap_rep.length;
120 if (ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc))
123 krb5_free_ap_rep_enc_part(context, ap_rep_enc);
125 /* extract and decrypt the result */
127 cipherresult.data = ptr;
128 cipherresult.length = (packet->data + packet->length) - ptr;
130 /* XXX there's no api to do this right. The problem is that
131 if there's a remote subkey, it will be used. This is
132 not what the spec requires */
134 tmp = auth_context->remote_subkey;
135 auth_context->remote_subkey = NULL;
137 ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
140 auth_context->remote_subkey = tmp;
145 cipherresult.data = ptr;
146 cipherresult.length = (packet->data + packet->length) - ptr;
148 if (ret = krb5_rd_error(context, &cipherresult, &krberror))
151 clearresult = krberror->e_data;
154 if (clearresult.length < 2) {
155 ret = KRB5KRB_AP_ERR_MODIFIED;
159 ptr = clearresult.data;
161 *result_code = (*ptr++ & 0xff);
162 *result_code = (*result_code<<8) | (*ptr++ & 0xff);
164 if ((*result_code < KRB5_KPASSWD_SUCCESS) ||
165 (*result_code > KRB5_KPASSWD_SOFTERROR)) {
166 ret = KRB5KRB_AP_ERR_MODIFIED;
170 /* all success replies should be authenticated/encrypted */
172 if ((ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS)) {
173 ret = KRB5KRB_AP_ERR_MODIFIED;
177 result_data->length = (clearresult.data + clearresult.length) - ptr;
179 if (result_data->length) {
180 result_data->data = (char *) malloc(result_data->length);
181 if (result_data->data == NULL) {
185 memcpy(result_data->data, ptr, result_data->length);
187 result_data->data = NULL;
194 krb5_xfree(clearresult.data);
196 krb5_free_error(context, krberror);
202 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
203 krb5_chpw_result_code_string(context, result_code, code_string)
204 krb5_context context;
208 switch (result_code) {
209 case KRB5_KPASSWD_MALFORMED:
210 *code_string = "Malformed request error";
212 case KRB5_KPASSWD_HARDERROR:
213 *code_string = "Server error";
215 case KRB5_KPASSWD_AUTHERROR:
216 *code_string = "Authentication error";
218 case KRB5_KPASSWD_SOFTERROR:
219 *code_string = "Password change rejected";
222 *code_string = "Password change failed";