src/plugins/auth-pam/utils.c
4507bb6c
 /*
  *  OpenVPN -- An application to securely tunnel IP networks
  *             over a single TCP/UDP port, with support for SSL/TLS-based
  *             session authentication and key exchange,
  *             packet encryption, packet authentication, and
  *             packet compression.
  *
58716979
  *  Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
4507bb6c
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
  *  as published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program (see the file COPYING included with this
  *  distribution); if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
  * OpenVPN plugin module to do PAM authentication using a split
  * privilege model.
  */
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 
 #include <string.h>
 #include <ctype.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <stdint.h>
 
 #include "utils.h"
 
 char *
 searchandreplace(const char *tosearch, const char *searchfor, const char *replacewith)
 {
81d882d5
     if (!tosearch || !searchfor || !replacewith)
     {
         return NULL;
     }
4507bb6c
 
81d882d5
     size_t tosearchlen = strlen(tosearch);
     size_t replacewithlen = strlen(replacewith);
     size_t templen = tosearchlen * replacewithlen;
4507bb6c
 
81d882d5
     if (tosearchlen == 0 || strlen(searchfor) == 0 || replacewithlen == 0)
     {
         return NULL;
     }
4507bb6c
 
81d882d5
     bool is_potential_integer_overflow =  (templen == SIZE_MAX) || (templen / tosearchlen != replacewithlen);
4507bb6c
 
81d882d5
     if (is_potential_integer_overflow)
     {
         return NULL;
     }
4507bb6c
 
81d882d5
     /* state: all parameters are valid */
4507bb6c
 
81d882d5
     const char *searching = tosearch;
     char *scratch;
4507bb6c
 
81d882d5
     char temp[templen+1];
     temp[0] = 0;
4507bb6c
 
81d882d5
     scratch = strstr(searching,searchfor);
     if (!scratch)
     {
         return strdup(tosearch);
     }
4507bb6c
 
81d882d5
     while (scratch) {
         strncat(temp,searching,scratch-searching);
         strcat(temp,replacewith);
4507bb6c
 
81d882d5
         searching = scratch+strlen(searchfor);
         scratch = strstr(searching,searchfor);
     }
     return strdup(temp);
4507bb6c
 }
 
 const char *
81d882d5
 get_env(const char *name, const char *envp[])
4507bb6c
 {
81d882d5
     if (envp)
4507bb6c
     {
81d882d5
         int i;
         const int namelen = strlen(name);
         for (i = 0; envp[i]; ++i)
         {
             if (!strncmp(envp[i], name, namelen))
             {
                 const char *cp = envp[i] + namelen;
                 if (*cp == '=')
                 {
                     return cp + 1;
                 }
             }
         }
4507bb6c
     }
81d882d5
     return NULL;
4507bb6c
 }
 
 int
81d882d5
 string_array_len(const char *array[])
4507bb6c
 {
81d882d5
     int i = 0;
     if (array)
4507bb6c
     {
81d882d5
         while (array[i])
             ++i;
4507bb6c
     }
81d882d5
     return i;
4507bb6c
 }