obsolete.c

Go to the documentation of this file.
00001 /* obsolete.c --- Obsolete functions kept around for backwards compatibility.
00002  * Copyright (C) 2002, 2003, 2004, 2005, 2006  Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License License along with GNU SASL Library; if not, write to the
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "internal.h"
00024 
00040 int
00041 gsasl_client_listmech (Gsasl * ctx, char *out, size_t * outlen)
00042 {
00043   char *tmp;
00044   int rc;
00045 
00046   rc = gsasl_client_mechlist (ctx, &tmp);
00047 
00048   if (rc == GSASL_OK)
00049     {
00050       size_t tmplen = strlen (tmp);
00051 
00052       if (tmplen >= *outlen)
00053         {
00054           free (tmp);
00055           return GSASL_TOO_SMALL_BUFFER;
00056         }
00057 
00058       if (out)
00059         strcpy (out, tmp);
00060       *outlen = tmplen + 1;
00061       free (tmp);
00062     }
00063 
00064   return rc;
00065 }
00066 
00082 int
00083 gsasl_server_listmech (Gsasl * ctx, char *out, size_t * outlen)
00084 {
00085   char *tmp;
00086   int rc;
00087 
00088   rc = gsasl_server_mechlist (ctx, &tmp);
00089 
00090   if (rc == GSASL_OK)
00091     {
00092       size_t tmplen = strlen (tmp);
00093 
00094       if (tmplen >= *outlen)
00095         {
00096           free (tmp);
00097           return GSASL_TOO_SMALL_BUFFER;
00098         }
00099 
00100       if (out)
00101         strcpy (out, tmp);
00102       *outlen = tmplen + 1;
00103       free (tmp);
00104     }
00105 
00106   return rc;
00107 }
00108 
00109 static int
00110 _gsasl_step (Gsasl_session * sctx,
00111              const char *input, size_t input_len,
00112              char *output, size_t * output_len)
00113 {
00114   char *tmp;
00115   size_t tmplen;
00116   int rc;
00117 
00118   rc = gsasl_step (sctx, input, input_len, &tmp, &tmplen);
00119 
00120   if (rc == GSASL_OK || rc == GSASL_NEEDS_MORE)
00121     {
00122       if (tmplen >= *output_len)
00123         {
00124           free (tmp);
00125           /* XXX We lose the step token here, don't we? */
00126           return GSASL_TOO_SMALL_BUFFER;
00127         }
00128 
00129       if (output)
00130         memcpy (output, tmp, tmplen);
00131       *output_len = tmplen;
00132       free (tmp);
00133     }
00134 
00135   return rc;
00136 }
00137 
00160 int
00161 gsasl_client_step (Gsasl_session * sctx,
00162                    const char *input,
00163                    size_t input_len, char *output, size_t * output_len)
00164 {
00165   return _gsasl_step (sctx, input, input_len, output, output_len);
00166 }
00167 
00190 int
00191 gsasl_server_step (Gsasl_session * sctx,
00192                    const char *input,
00193                    size_t input_len, char *output, size_t * output_len)
00194 {
00195   return _gsasl_step (sctx, input, input_len, output, output_len);
00196 }
00197 
00198 static int
00199 _gsasl_step64 (Gsasl_session * sctx,
00200                const char *b64input, char *b64output, size_t b64output_len)
00201 {
00202   char *tmp;
00203   int rc;
00204 
00205   rc = gsasl_step64 (sctx, b64input, &tmp);
00206 
00207   if (rc == GSASL_OK || rc == GSASL_NEEDS_MORE)
00208     {
00209       if (b64output_len <= strlen (tmp))
00210         {
00211           free (tmp);
00212           /* XXX We lose the step token here, don't we? */
00213           return GSASL_TOO_SMALL_BUFFER;
00214         }
00215 
00216       if (b64output)
00217         strcpy (b64output, tmp);
00218       free (tmp);
00219     }
00220 
00221   return rc;
00222 }
00223 
00238 int
00239 gsasl_client_step_base64 (Gsasl_session * sctx,
00240                           const char *b64input,
00241                           char *b64output, size_t b64output_len)
00242 {
00243   return _gsasl_step64 (sctx, b64input, b64output, b64output_len);
00244 }
00245 
00260 int
00261 gsasl_server_step_base64 (Gsasl_session * sctx,
00262                           const char *b64input,
00263                           char *b64output, size_t b64output_len)
00264 {
00265   return _gsasl_step64 (sctx, b64input, b64output, b64output_len);
00266 }
00267 
00277 void
00278 gsasl_client_finish (Gsasl_session * sctx)
00279 {
00280   gsasl_finish (sctx);
00281 }
00282 
00292 void
00293 gsasl_server_finish (Gsasl_session * sctx)
00294 {
00295   gsasl_finish (sctx);
00296 }
00297 
00306 Gsasl *
00307 gsasl_client_ctx_get (Gsasl_session * sctx)
00308 {
00309   return sctx->ctx;
00310 }
00311 
00326 void
00327 gsasl_client_application_data_set (Gsasl_session * sctx,
00328                                    void *application_data)
00329 {
00330   gsasl_appinfo_set (sctx, application_data);
00331 }
00332 
00347 void *
00348 gsasl_client_application_data_get (Gsasl_session * sctx)
00349 {
00350   return gsasl_appinfo_get (sctx);
00351 }
00352 
00361 Gsasl *
00362 gsasl_server_ctx_get (Gsasl_session * sctx)
00363 {
00364   return sctx->ctx;
00365 }
00366 
00381 void
00382 gsasl_server_application_data_set (Gsasl_session * sctx,
00383                                    void *application_data)
00384 {
00385   gsasl_appinfo_set (sctx, application_data);
00386 }
00387 
00402 void *
00403 gsasl_server_application_data_get (Gsasl_session * sctx)
00404 {
00405   return gsasl_appinfo_get (sctx);
00406 }
00407 
00421 int
00422 gsasl_randomize (int strong, char *data, size_t datalen)
00423 {
00424   if (strong)
00425     return gsasl_random (data, datalen);
00426   return gsasl_nonce (data, datalen);
00427 }
00428 
00437 Gsasl *
00438 gsasl_ctx_get (Gsasl_session * sctx)
00439 {
00440   return sctx->ctx;
00441 }
00442 
00461 int
00462 gsasl_encode_inline (Gsasl_session * sctx,
00463                      const char *input, size_t input_len,
00464                      char *output, size_t * output_len)
00465 {
00466   char *tmp;
00467   size_t tmplen;
00468   int res;
00469 
00470   res = gsasl_encode (sctx, input, input_len, &tmp, &tmplen);
00471   if (res == GSASL_OK)
00472     {
00473       if (*output_len < tmplen)
00474         return GSASL_TOO_SMALL_BUFFER;
00475       *output_len = tmplen;
00476       memcpy (output, tmp, tmplen);
00477       free (output);
00478     }
00479 
00480   return res;
00481 }
00482 
00501 int
00502 gsasl_decode_inline (Gsasl_session * sctx,
00503                      const char *input, size_t input_len,
00504                      char *output, size_t * output_len)
00505 {
00506   char *tmp;
00507   size_t tmplen;
00508   int res;
00509 
00510   res = gsasl_decode (sctx, input, input_len, &tmp, &tmplen);
00511   if (res == GSASL_OK)
00512     {
00513       if (*output_len < tmplen)
00514         return GSASL_TOO_SMALL_BUFFER;
00515       *output_len = tmplen;
00516       memcpy (output, tmp, tmplen);
00517       free (output);
00518     }
00519 
00520   return res;
00521 }
00522 
00536 void
00537 gsasl_application_data_set (Gsasl * ctx, void *appdata)
00538 {
00539   ctx->application_hook = appdata;
00540 }
00541 
00555 void *
00556 gsasl_application_data_get (Gsasl * ctx)
00557 {
00558   return ctx->application_hook;
00559 }
00560 
00574 void
00575 gsasl_appinfo_set (Gsasl_session * sctx, void *appdata)
00576 {
00577   sctx->application_data = appdata;
00578 }
00579 
00593 void *
00594 gsasl_appinfo_get (Gsasl_session * sctx)
00595 {
00596   return sctx->application_data;
00597 }
00598 
00611 const char *
00612 gsasl_server_suggest_mechanism (Gsasl * ctx, const char *mechlist)
00613 {
00614   return NULL;                  /* This function is just silly. */
00615 }
00616 
00631 void
00632 gsasl_client_callback_authentication_id_set (Gsasl * ctx,
00633                                              Gsasl_client_callback_authentication_id
00634                                              cb)
00635 {
00636   ctx->cbc_authentication_id = cb;
00637 }
00638 
00651 Gsasl_client_callback_authentication_id
00652 gsasl_client_callback_authentication_id_get (Gsasl * ctx)
00653 {
00654   return ctx ? ctx->cbc_authentication_id : NULL;
00655 }
00656 
00671 void
00672 gsasl_client_callback_authorization_id_set (Gsasl * ctx,
00673                                             Gsasl_client_callback_authorization_id
00674                                             cb)
00675 {
00676   ctx->cbc_authorization_id = cb;
00677 }
00678 
00691 Gsasl_client_callback_authorization_id
00692 gsasl_client_callback_authorization_id_get (Gsasl * ctx)
00693 {
00694   return ctx ? ctx->cbc_authorization_id : NULL;
00695 }
00696 
00711 void
00712 gsasl_client_callback_password_set (Gsasl * ctx,
00713                                     Gsasl_client_callback_password cb)
00714 {
00715   ctx->cbc_password = cb;
00716 }
00717 
00718 
00731 Gsasl_client_callback_password
00732 gsasl_client_callback_password_get (Gsasl * ctx)
00733 {
00734   return ctx ? ctx->cbc_password : NULL;
00735 }
00736 
00751 void
00752 gsasl_client_callback_passcode_set (Gsasl * ctx,
00753                                     Gsasl_client_callback_passcode cb)
00754 {
00755   ctx->cbc_passcode = cb;
00756 }
00757 
00758 
00771 Gsasl_client_callback_passcode
00772 gsasl_client_callback_passcode_get (Gsasl * ctx)
00773 {
00774   return ctx ? ctx->cbc_passcode : NULL;
00775 }
00776 
00793 void
00794 gsasl_client_callback_pin_set (Gsasl * ctx, Gsasl_client_callback_pin cb)
00795 {
00796   ctx->cbc_pin = cb;
00797 }
00798 
00799 
00812 Gsasl_client_callback_pin
00813 gsasl_client_callback_pin_get (Gsasl * ctx)
00814 {
00815   return ctx ? ctx->cbc_pin : NULL;
00816 }
00817 
00835 void
00836 gsasl_client_callback_service_set (Gsasl * ctx,
00837                                    Gsasl_client_callback_service cb)
00838 {
00839   ctx->cbc_service = cb;
00840 }
00841 
00854 Gsasl_client_callback_service
00855 gsasl_client_callback_service_get (Gsasl * ctx)
00856 {
00857   return ctx ? ctx->cbc_service : NULL;
00858 }
00859 
00875 void
00876 gsasl_client_callback_anonymous_set (Gsasl * ctx,
00877                                      Gsasl_client_callback_anonymous cb)
00878 {
00879   ctx->cbc_anonymous = cb;
00880 }
00881 
00894 Gsasl_client_callback_anonymous
00895 gsasl_client_callback_anonymous_get (Gsasl * ctx)
00896 {
00897   return ctx ? ctx->cbc_anonymous : NULL;
00898 }
00899 
00914 void
00915 gsasl_client_callback_qop_set (Gsasl * ctx, Gsasl_client_callback_qop cb)
00916 {
00917   ctx->cbc_qop = cb;
00918 }
00919 
00932 Gsasl_client_callback_qop
00933 gsasl_client_callback_qop_get (Gsasl * ctx)
00934 {
00935   return ctx ? ctx->cbc_qop : NULL;
00936 }
00937 
00955 void
00956 gsasl_client_callback_maxbuf_set (Gsasl * ctx,
00957                                   Gsasl_client_callback_maxbuf cb)
00958 {
00959   ctx->cbc_maxbuf = cb;
00960 }
00961 
00974 Gsasl_client_callback_maxbuf
00975 gsasl_client_callback_maxbuf_get (Gsasl * ctx)
00976 {
00977   return ctx ? ctx->cbc_maxbuf : NULL;
00978 }
00979 
00995 void
00996 gsasl_client_callback_realm_set (Gsasl * ctx, Gsasl_client_callback_realm cb)
00997 {
00998   ctx->cbc_realm = cb;
00999 }
01000 
01013 Gsasl_client_callback_realm
01014 gsasl_client_callback_realm_get (Gsasl * ctx)
01015 {
01016   return ctx ? ctx->cbc_realm : NULL;
01017 }
01018 
01034 void
01035 gsasl_server_callback_validate_set (Gsasl * ctx,
01036                                     Gsasl_server_callback_validate cb)
01037 {
01038   ctx->cbs_validate = cb;
01039 }
01040 
01053 Gsasl_server_callback_validate
01054 gsasl_server_callback_validate_get (Gsasl * ctx)
01055 {
01056   return ctx ? ctx->cbs_validate : NULL;
01057 }
01058 
01074 void
01075 gsasl_server_callback_retrieve_set (Gsasl * ctx,
01076                                     Gsasl_server_callback_retrieve cb)
01077 {
01078   ctx->cbs_retrieve = cb;
01079 }
01080 
01093 Gsasl_server_callback_retrieve
01094 gsasl_server_callback_retrieve_get (Gsasl * ctx)
01095 {
01096   return ctx ? ctx->cbs_retrieve : NULL;
01097 }
01098 
01114 void
01115 gsasl_server_callback_cram_md5_set (Gsasl * ctx,
01116                                     Gsasl_server_callback_cram_md5 cb)
01117 {
01118   ctx->cbs_cram_md5 = cb;
01119 }
01120 
01133 Gsasl_server_callback_cram_md5
01134 gsasl_server_callback_cram_md5_get (Gsasl * ctx)
01135 {
01136   return ctx ? ctx->cbs_cram_md5 : NULL;
01137 }
01138 
01154 void
01155 gsasl_server_callback_digest_md5_set (Gsasl * ctx,
01156                                       Gsasl_server_callback_digest_md5 cb)
01157 {
01158   ctx->cbs_digest_md5 = cb;
01159 }
01160 
01173 Gsasl_server_callback_digest_md5
01174 gsasl_server_callback_digest_md5_get (Gsasl * ctx)
01175 {
01176   return ctx->cbs_digest_md5;
01177 }
01178 
01193 void
01194 gsasl_server_callback_external_set (Gsasl * ctx,
01195                                     Gsasl_server_callback_external cb)
01196 {
01197   ctx->cbs_external = cb;
01198 }
01199 
01212 Gsasl_server_callback_external
01213 gsasl_server_callback_external_get (Gsasl * ctx)
01214 {
01215   return ctx ? ctx->cbs_external : NULL;
01216 }
01217 
01232 void
01233 gsasl_server_callback_anonymous_set (Gsasl * ctx,
01234                                      Gsasl_server_callback_anonymous cb)
01235 {
01236   ctx->cbs_anonymous = cb;
01237 }
01238 
01251 Gsasl_server_callback_anonymous
01252 gsasl_server_callback_anonymous_get (Gsasl * ctx)
01253 {
01254   return ctx ? ctx->cbs_anonymous : NULL;
01255 }
01256 
01272 void
01273 gsasl_server_callback_realm_set (Gsasl * ctx, Gsasl_server_callback_realm cb)
01274 {
01275   ctx->cbs_realm = cb;
01276 }
01277 
01290 Gsasl_server_callback_realm
01291 gsasl_server_callback_realm_get (Gsasl * ctx)
01292 {
01293   return ctx ? ctx->cbs_realm : NULL;
01294 }
01295 
01312 void
01313 gsasl_server_callback_qop_set (Gsasl * ctx, Gsasl_server_callback_qop cb)
01314 {
01315   ctx->cbs_qop = cb;
01316 }
01317 
01330 Gsasl_server_callback_qop
01331 gsasl_server_callback_qop_get (Gsasl * ctx)
01332 {
01333   return ctx ? ctx->cbs_qop : NULL;
01334 }
01335 
01353 void
01354 gsasl_server_callback_maxbuf_set (Gsasl * ctx,
01355                                   Gsasl_server_callback_maxbuf cb)
01356 {
01357   ctx->cbs_maxbuf = cb;
01358 }
01359 
01372 Gsasl_server_callback_maxbuf
01373 gsasl_server_callback_maxbuf_get (Gsasl * ctx)
01374 {
01375   return ctx ? ctx->cbs_maxbuf : NULL;
01376 }
01377 
01394 void
01395 gsasl_server_callback_cipher_set (Gsasl * ctx,
01396                                   Gsasl_server_callback_cipher cb)
01397 {
01398   ctx->cbs_cipher = cb;
01399 }
01400 
01413 Gsasl_server_callback_cipher
01414 gsasl_server_callback_cipher_get (Gsasl * ctx)
01415 {
01416   return ctx ? ctx->cbs_cipher : NULL;
01417 }
01418 
01440 void
01441 gsasl_server_callback_securid_set (Gsasl * ctx,
01442                                    Gsasl_server_callback_securid cb)
01443 {
01444   ctx->cbs_securid = cb;
01445 }
01446 
01459 Gsasl_server_callback_securid
01460 gsasl_server_callback_securid_get (Gsasl * ctx)
01461 {
01462   return ctx ? ctx->cbs_securid : NULL;
01463 }
01464 
01482 void
01483 gsasl_server_callback_gssapi_set (Gsasl * ctx,
01484                                   Gsasl_server_callback_gssapi cb)
01485 {
01486   ctx->cbs_gssapi = cb;
01487 }
01488 
01501 Gsasl_server_callback_gssapi
01502 gsasl_server_callback_gssapi_get (Gsasl * ctx)
01503 {
01504   return ctx ? ctx->cbs_gssapi : NULL;
01505 }
01506 
01523 void
01524 gsasl_server_callback_service_set (Gsasl * ctx,
01525                                    Gsasl_server_callback_service cb)
01526 {
01527   ctx->cbs_service = cb;
01528 }
01529 
01542 Gsasl_server_callback_service
01543 gsasl_server_callback_service_get (Gsasl * ctx)
01544 {
01545   return ctx ? ctx->cbs_service : NULL;
01546 }
01547 
01548 #if WITH_SASLPREP
01549 # include <stringprep.h>
01550 #endif
01551 
01578 char *
01579 gsasl_stringprep_nfkc (const char *in, ssize_t len)
01580 {
01581   char *out = NULL;
01582 
01583 #if WITH_SASLPREP
01584   out = stringprep_utf8_nfkc_normalize (in, len);
01585 #endif
01586 
01587   return out;
01588 }
01589 
01609 char *
01610 gsasl_stringprep_saslprep (const char *in, int *stringprep_rc)
01611 {
01612   char *out = NULL;
01613 #if WITH_SASLPREP
01614   int rc;
01615 
01616   rc = stringprep_profile (in, &out, "SASLprep", 0);
01617   if (stringprep_rc)
01618     *stringprep_rc = rc;
01619   if (rc != STRINGPREP_OK)
01620     out = NULL;
01621 #endif
01622 
01623   return out;
01624 }
01625 
01643 char *
01644 gsasl_stringprep_trace (const char *in, int *stringprep_rc)
01645 {
01646   char *out = NULL;
01647 #if WITH_SASLPREP
01648   int rc;
01649 
01650   rc = stringprep_profile (in, &out, "trace", 0);
01651   if (stringprep_rc)
01652     *stringprep_rc = rc;
01653   if (rc != STRINGPREP_OK)
01654     out = NULL;
01655 #endif
01656 
01657   return out;
01658 }
01659 
01684 int
01685 gsasl_md5pwd_get_password (const char *filename,
01686                            const char *username, char *key, size_t * keylen)
01687 {
01688   char matchbuf[BUFSIZ];
01689   char line[BUFSIZ];
01690   FILE *fh;
01691 
01692   fh = fopen (filename, "r");
01693   if (fh == NULL)
01694     return GSASL_FOPEN_ERROR;
01695 
01696   sprintf (matchbuf, "%s\t", username);
01697 
01698   while (!feof (fh))
01699     {
01700       if (fgets (line, BUFSIZ, fh) == NULL)
01701         break;
01702 
01703       if (line[0] == '#')
01704         continue;
01705 
01706       while (strlen (line) > 0 && (line[strlen (line) - 1] == '\n' ||
01707                                    line[strlen (line) - 1] == '\r'))
01708         line[strlen (line) - 1] = '\0';
01709 
01710       if (strlen (line) <= strlen (matchbuf))
01711         continue;
01712 
01713       if (strncmp (matchbuf, line, strlen (matchbuf)) == 0)
01714         {
01715           if (*keylen < strlen (line) - strlen (matchbuf))
01716             {
01717               fclose (fh);
01718               return GSASL_TOO_SMALL_BUFFER;
01719             }
01720 
01721           *keylen = strlen (line) - strlen (matchbuf);
01722 
01723           if (key)
01724             memcpy (key, &line[strlen (matchbuf)], *keylen);
01725 
01726           fclose (fh);
01727 
01728           return GSASL_OK;
01729         }
01730     }
01731 
01732   if (fclose (fh) != 0)
01733     return GSASL_FCLOSE_ERROR;
01734 
01735   return GSASL_AUTHENTICATION_ERROR;
01736 }
01737 
01738 
01739 /*
01740  * Copyright (c) 1996-1999 by Internet Software Consortium.
01741  *
01742  * Permission to use, copy, modify, and distribute this software for any
01743  * purpose with or without fee is hereby granted, provided that the above
01744  * copyright notice and this permission notice appear in all copies.
01745  *
01746  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
01747  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
01748  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
01749  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
01750  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
01751  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
01752  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
01753  * SOFTWARE.
01754  */
01755 
01756 /*
01757  * Portions Copyright (c) 1995 by International Business Machines, Inc.
01758  *
01759  * International Business Machines, Inc. (hereinafter called IBM) grants
01760  * permission under its copyrights to use, copy, modify, and distribute this
01761  * Software with or without fee, provided that the above copyright notice and
01762  * all paragraphs of this notice appear in all copies, and that the name of IBM
01763  * not be used in connection with the marketing of any product incorporating
01764  * the Software or modifications thereof, without specific, written prior
01765  * permission.
01766  *
01767  * To the extent it has a right to do so, IBM grants an immunity from suit
01768  * under its patents, if any, for the use, sale or manufacture of products to
01769  * the extent that such products are used for performing Domain Name System
01770  * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
01771  * granted for any product per se or for any other function of any product.
01772  *
01773  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
01774  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
01775  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
01776  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
01777  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
01778  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
01779  */
01780 
01781 #include <ctype.h>
01782 #include <stdio.h>
01783 
01784 #define Assert(Cond) if (!(Cond)) abort()
01785 
01786 static const char Base64[] =
01787   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
01788 static const char Pad64 = '=';
01789 
01806 int
01807 gsasl_base64_encode (char const *src,
01808                      size_t srclength, char *target, size_t targsize)
01809 {
01810   size_t datalength = 0;
01811   unsigned char input[3];
01812   unsigned char output[4];
01813   size_t i;
01814 
01815   while (2 < srclength)
01816     {
01817       input[0] = *src++;
01818       input[1] = *src++;
01819       input[2] = *src++;
01820       srclength -= 3;
01821 
01822       output[0] = input[0] >> 2;
01823       output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
01824       output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
01825       output[3] = input[2] & 0x3f;
01826       Assert (output[0] < 64);
01827       Assert (output[1] < 64);
01828       Assert (output[2] < 64);
01829       Assert (output[3] < 64);
01830 
01831       if (datalength + 4 > targsize)
01832         return (-1);
01833       target[datalength++] = Base64[output[0]];
01834       target[datalength++] = Base64[output[1]];
01835       target[datalength++] = Base64[output[2]];
01836       target[datalength++] = Base64[output[3]];
01837     }
01838 
01839   /* Now we worry about padding. */
01840   if (0 != srclength)
01841     {
01842       /* Get what's left. */
01843       input[0] = input[1] = input[2] = '\0';
01844       for (i = 0; i < srclength; i++)
01845         input[i] = *src++;
01846 
01847       output[0] = input[0] >> 2;
01848       output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
01849       output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
01850       Assert (output[0] < 64);
01851       Assert (output[1] < 64);
01852       Assert (output[2] < 64);
01853 
01854       if (datalength + 4 > targsize)
01855         return (-1);
01856       target[datalength++] = Base64[output[0]];
01857       target[datalength++] = Base64[output[1]];
01858       if (srclength == 1)
01859         target[datalength++] = Pad64;
01860       else
01861         target[datalength++] = Base64[output[2]];
01862       target[datalength++] = Pad64;
01863     }
01864   if (datalength >= targsize)
01865     return (-1);
01866   target[datalength] = '\0';    /* Returned value doesn't count \0. */
01867   return (datalength);
01868 }
01869 
01885 int
01886 gsasl_base64_decode (char const *src, char *target, size_t targsize)
01887 {
01888   int tarindex, state, ch;
01889   char *pos;
01890 
01891   state = 0;
01892   tarindex = 0;
01893 
01894   while ((ch = *src++) != '\0')
01895     {
01896       if (isspace (ch))         /* Skip whitespace anywhere. */
01897         continue;
01898 
01899       if (ch == Pad64)
01900         break;
01901 
01902       pos = strchr (Base64, ch);
01903       if (pos == 0)             /* A non-base64 character. */
01904         return (-1);
01905 
01906       switch (state)
01907         {
01908         case 0:
01909           if (target)
01910             {
01911               if ((size_t) tarindex >= targsize)
01912                 return (-1);
01913               target[tarindex] = (pos - Base64) << 2;
01914             }
01915           state = 1;
01916           break;
01917         case 1:
01918           if (target)
01919             {
01920               if ((size_t) tarindex + 1 >= targsize)
01921                 return (-1);
01922               target[tarindex] |= (pos - Base64) >> 4;
01923               target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4;
01924             }
01925           tarindex++;
01926           state = 2;
01927           break;
01928         case 2:
01929           if (target)
01930             {
01931               if ((size_t) tarindex + 1 >= targsize)
01932                 return (-1);
01933               target[tarindex] |= (pos - Base64) >> 2;
01934               target[tarindex + 1] = ((pos - Base64) & 0x03) << 6;
01935             }
01936           tarindex++;
01937           state = 3;
01938           break;
01939         case 3:
01940           if (target)
01941             {
01942               if ((size_t) tarindex >= targsize)
01943                 return (-1);
01944               target[tarindex] |= (pos - Base64);
01945             }
01946           tarindex++;
01947           state = 0;
01948           break;
01949         default:
01950           abort ();
01951         }
01952     }
01953 
01954   /*
01955    * We are done decoding Base-64 chars.  Let's see if we ended
01956    * on a byte boundary, and/or with erroneous trailing characters.
01957    */
01958 
01959   if (ch == Pad64)
01960     {                           /* We got a pad char. */
01961       ch = *src++;              /* Skip it, get next. */
01962       switch (state)
01963         {
01964         case 0:         /* Invalid = in first position */
01965         case 1:         /* Invalid = in second position */
01966           return (-1);
01967 
01968         case 2:         /* Valid, means one byte of info */
01969           /* Skip any number of spaces. */
01970           for ((void) NULL; ch != '\0'; ch = *src++)
01971             if (!isspace (ch))
01972               break;
01973           /* Make sure there is another trailing = sign. */
01974           if (ch != Pad64)
01975             return (-1);
01976           ch = *src++;          /* Skip the = */
01977           /* Fall through to "single trailing =" case. */
01978           /* FALLTHROUGH */
01979 
01980         case 3:         /* Valid, means two bytes of info */
01981           /*
01982            * We know this char is an =.  Is there anything but
01983            * whitespace after it?
01984            */
01985           for ((void) NULL; ch != '\0'; ch = *src++)
01986             if (!isspace (ch))
01987               return (-1);
01988 
01989           /*
01990            * Now make sure for cases 2 and 3 that the "extra"
01991            * bits that slopped past the last full byte were
01992            * zeros.  If we don't check them, they become a
01993            * subliminal channel.
01994            */
01995           if (target && target[tarindex] != 0)
01996             return (-1);
01997         }
01998     }
01999   else
02000     {
02001       /*
02002        * We ended by seeing the end of the string.  Make sure we
02003        * have no partial bytes lying around.
02004        */
02005       if (state != 0)
02006         return (-1);
02007     }
02008 
02009   return (tarindex);
02010 }

Generated on Tue Aug 22 12:06:06 2006 for gsasl by  doxygen 1.4.7