1b967cddfSBarry Smith 20efc6a03SBarry Smith #include <petscwebclient.h> 3*bb04b57dSBarry Smith #pragma clang diagnostic ignored "-Wdeprecated-declarations" 4b967cddfSBarry Smith 5b967cddfSBarry Smith static BIO *bio_err = NULL; 6b967cddfSBarry Smith 7b967cddfSBarry Smith #define PASSWORD "password" 8b967cddfSBarry Smith 94a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 10b967cddfSBarry Smith static int password_cb(char *buf,int num, int rwflag,void *userdata) 11b967cddfSBarry Smith { 12b967cddfSBarry Smith if (num < strlen(PASSWORD)+1) return(0); 13b967cddfSBarry Smith strcpy(buf,PASSWORD); 14b967cddfSBarry Smith return(strlen(PASSWORD)); 15b967cddfSBarry Smith } 16b967cddfSBarry Smith #endif 17b967cddfSBarry Smith 18b967cddfSBarry Smith static void sigpipe_handle(int x) 19b967cddfSBarry Smith { 20b967cddfSBarry Smith } 21b967cddfSBarry Smith 22b967cddfSBarry Smith #undef __FUNCT__ 23b967cddfSBarry Smith #define __FUNCT__ "PetscSSLInitializeContext" 24b967cddfSBarry Smith /* 25b967cddfSBarry Smith PetscSSLInitializeContext - Set up an SSL context suitable for initiating HTTPS requests. 26b967cddfSBarry Smith 274a285bdaSBarry Smith If built with PETSC_USE_SSL_CERTIFICATE requires the user have created a self-signed certificate with 28b967cddfSBarry Smith 2968e69593SBarry Smith $ saws/CA.pl -newcert (using the passphrase of password) 30b967cddfSBarry Smith $ cat newkey.pem newcert.pem > sslclient.pem 31b967cddfSBarry Smith 32b967cddfSBarry Smith and put the resulting file in either the current directory (with the application) or in the home directory. This seems kind of 33b967cddfSBarry Smith silly but it was all I could figure out. 34b967cddfSBarry Smith 35b967cddfSBarry Smith */ 36b967cddfSBarry Smith PetscErrorCode PetscSSLInitializeContext(SSL_CTX **octx) 37b967cddfSBarry Smith { 38b967cddfSBarry Smith SSL_CTX *ctx; 394a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 40b967cddfSBarry Smith char keyfile[PETSC_MAX_PATH_LEN]; 41b967cddfSBarry Smith PetscBool exists; 42b967cddfSBarry Smith PetscErrorCode ierr; 43b967cddfSBarry Smith #endif 44b967cddfSBarry Smith 45b967cddfSBarry Smith PetscFunctionBegin; 46b967cddfSBarry Smith if (!bio_err){ 47b967cddfSBarry Smith SSL_library_init(); 48b967cddfSBarry Smith SSL_load_error_strings(); 49b967cddfSBarry Smith bio_err = BIO_new_fp(stderr,BIO_NOCLOSE); 50b967cddfSBarry Smith } 51b967cddfSBarry Smith 52b967cddfSBarry Smith /* Set up a SIGPIPE handler */ 53b967cddfSBarry Smith signal(SIGPIPE,sigpipe_handle); 54b967cddfSBarry Smith 55d8dcb26dSBarry Smith ctx = SSL_CTX_new(SSLv23_method()); 565dc0f0a4SBarry Smith SSL_CTX_set_mode(ctx,SSL_MODE_AUTO_RETRY); 57b967cddfSBarry Smith 584a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 59b967cddfSBarry Smith /* Locate keyfile */ 60b967cddfSBarry Smith ierr = PetscStrcpy(keyfile,"sslclient.pem");CHKERRQ(ierr); 61b967cddfSBarry Smith ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); 62b967cddfSBarry Smith if (!exists) { 63b967cddfSBarry Smith ierr = PetscGetHomeDirectory(keyfile,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 64b967cddfSBarry Smith ierr = PetscStrcat(keyfile,"/");CHKERRQ(ierr); 65b967cddfSBarry Smith ierr = PetscStrcat(keyfile,"sslclient.pem");CHKERRQ(ierr); 66b967cddfSBarry Smith ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); 67b967cddfSBarry Smith if (!exists) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate sslclient.pem file in current directory or home directory"); 68b967cddfSBarry Smith } 69b967cddfSBarry Smith 70b967cddfSBarry Smith /* Load our keys and certificates*/ 71b967cddfSBarry Smith if (!(SSL_CTX_use_certificate_chain_file(ctx,keyfile))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read certificate file"); 72b967cddfSBarry Smith 73b967cddfSBarry Smith SSL_CTX_set_default_passwd_cb(ctx,password_cb); 74b967cddfSBarry Smith if (!(SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read key file"); 75b967cddfSBarry Smith #endif 76b967cddfSBarry Smith 77b967cddfSBarry Smith *octx = ctx; 78b967cddfSBarry Smith PetscFunctionReturn(0); 79b967cddfSBarry Smith } 80b967cddfSBarry Smith 81b967cddfSBarry Smith #undef __FUNCT__ 82b967cddfSBarry Smith #define __FUNCT__ "PetscSSLDestroyContext" 83b967cddfSBarry Smith PetscErrorCode PetscSSLDestroyContext(SSL_CTX *ctx) 84b967cddfSBarry Smith { 85b967cddfSBarry Smith PetscFunctionBegin; 86b967cddfSBarry Smith SSL_CTX_free(ctx); 87b967cddfSBarry Smith PetscFunctionReturn(0); 88b967cddfSBarry Smith } 89b967cddfSBarry Smith 90b967cddfSBarry Smith #undef __FUNCT__ 9104102261SBarry Smith #define __FUNCT__ "PetscHTTPBuildRequest" 9204102261SBarry Smith PetscErrorCode PetscHTTPBuildRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],char **outrequest) 93b967cddfSBarry Smith { 94b967cddfSBarry Smith char *request=0; 9593e1d32fSBarry Smith char contentlength[40],contenttype[80],*path,*host; 967a3410edSBarry Smith size_t request_len,headlen,bodylen,contentlen,pathlen,hostlen,typelen,contenttypelen = 0; 97b967cddfSBarry Smith PetscErrorCode ierr; 98b967cddfSBarry Smith PetscBool flg; 99b967cddfSBarry Smith 100b967cddfSBarry Smith PetscFunctionBegin; 10193e1d32fSBarry Smith ierr = PetscStrallocpy(url,&host);CHKERRQ(ierr); 10293e1d32fSBarry Smith ierr = PetscStrchr(host,'/',&path);CHKERRQ(ierr); 10393e1d32fSBarry Smith if (!path) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"url must contain / it is %s",url); 104c245270aSBarry Smith *path = 0; 10593e1d32fSBarry Smith ierr = PetscStrlen(host,&hostlen);CHKERRQ(ierr); 10693e1d32fSBarry Smith 10793e1d32fSBarry Smith ierr = PetscStrchr(url,'/',&path);CHKERRQ(ierr); 10893e1d32fSBarry Smith ierr = PetscStrlen(path,&pathlen);CHKERRQ(ierr); 10993e1d32fSBarry Smith 110b967cddfSBarry Smith if (header) { 111b967cddfSBarry Smith ierr = PetscStrendswith(header,"\r\n",&flg);CHKERRQ(ierr); 112b967cddfSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"header must end with \\r\\n"); 113b967cddfSBarry Smith } 114b967cddfSBarry Smith 115b967cddfSBarry Smith ierr = PetscStrlen(type,&typelen);CHKERRQ(ierr); 116b967cddfSBarry Smith if (ctype) { 117b967cddfSBarry Smith ierr = PetscSNPrintf(contenttype,80,"Content-Type: %s\r\n",ctype);CHKERRQ(ierr); 118b967cddfSBarry Smith ierr = PetscStrlen(contenttype,&contenttypelen);CHKERRQ(ierr); 119b967cddfSBarry Smith } 120b967cddfSBarry Smith ierr = PetscStrlen(header,&headlen);CHKERRQ(ierr); 121b967cddfSBarry Smith ierr = PetscStrlen(body,&bodylen);CHKERRQ(ierr); 122b967cddfSBarry Smith ierr = PetscSNPrintf(contentlength,40,"Content-Length: %d\r\n\r\n",(int)bodylen);CHKERRQ(ierr); 123b967cddfSBarry Smith ierr = PetscStrlen(contentlength,&contentlen);CHKERRQ(ierr); 124b967cddfSBarry Smith 125b967cddfSBarry Smith /* Now construct our HTTP request */ 12693e1d32fSBarry Smith request_len = typelen + 1 + pathlen + hostlen + 100 + headlen + contenttypelen + contentlen + bodylen + 1; 127fe278a28SBarry Smith ierr = PetscMalloc1(request_len,&request);CHKERRQ(ierr); 128b967cddfSBarry Smith ierr = PetscStrcpy(request,type);CHKERRQ(ierr); 129b967cddfSBarry Smith ierr = PetscStrcat(request," ");CHKERRQ(ierr); 13093e1d32fSBarry Smith ierr = PetscStrcat(request,path);CHKERRQ(ierr); 13193e1d32fSBarry Smith ierr = PetscStrcat(request," HTTP/1.1\r\nHost: ");CHKERRQ(ierr); 13293e1d32fSBarry Smith ierr = PetscStrcat(request,host);CHKERRQ(ierr); 13393e1d32fSBarry Smith ierr = PetscFree(host);CHKERRQ(ierr); 13493e1d32fSBarry Smith ierr = PetscStrcat(request,"\r\nUser-Agent:PETScClient\r\n");CHKERRQ(ierr); 135b967cddfSBarry Smith ierr = PetscStrcat(request,header);CHKERRQ(ierr); 136b967cddfSBarry Smith if (ctype) { 137b967cddfSBarry Smith ierr = PetscStrcat(request,contenttype);CHKERRQ(ierr); 138b967cddfSBarry Smith } 139b967cddfSBarry Smith ierr = PetscStrcat(request,contentlength);CHKERRQ(ierr); 140b967cddfSBarry Smith ierr = PetscStrcat(request,body);CHKERRQ(ierr); 141b967cddfSBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 142b967cddfSBarry Smith ierr = PetscInfo1(NULL,"HTTPS request follows: \n%s\n",request);CHKERRQ(ierr); 143b967cddfSBarry Smith 14404102261SBarry Smith *outrequest = request; 14504102261SBarry Smith PetscFunctionReturn(0); 14604102261SBarry Smith } 14704102261SBarry Smith 14804102261SBarry Smith 14904102261SBarry Smith #undef __FUNCT__ 15004102261SBarry Smith #define __FUNCT__ "PetscHTTPSRequest" 15104102261SBarry Smith /* 15204102261SBarry Smith PetscHTTPSRequest - Send a request to an HTTPS server 15304102261SBarry Smith 15404102261SBarry Smith Input Parameters: 15504102261SBarry Smith + type - either "POST" or "GET" 15604102261SBarry Smith . url - URL of request host/path 15704102261SBarry Smith . header - additional header information, may be NULL 15804102261SBarry Smith . ctype - data type of body, for example application/json 15904102261SBarry Smith . body - data to send to server 16004102261SBarry Smith . ssl - obtained with PetscHTTPSConnect() 16104102261SBarry Smith - buffsize - size of buffer 16204102261SBarry Smith 16304102261SBarry Smith Output Parameter: 16404102261SBarry Smith . buff - everything returned from server 16504102261SBarry Smith */ 16604102261SBarry Smith PetscErrorCode PetscHTTPSRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],SSL *ssl,char buff[],size_t buffsize) 16704102261SBarry Smith { 16804102261SBarry Smith char *request; 16904102261SBarry Smith int r; 17004102261SBarry Smith size_t request_len,len; 17104102261SBarry Smith PetscErrorCode ierr; 1725dc0f0a4SBarry Smith PetscBool foundbody = PETSC_FALSE; 17304102261SBarry Smith 17404102261SBarry Smith PetscFunctionBegin; 17504102261SBarry Smith ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr); 17604102261SBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 17704102261SBarry Smith 178d8dcb26dSBarry Smith r = SSL_write(ssl,request,(int)request_len); 179b967cddfSBarry Smith switch (SSL_get_error(ssl,r)){ 180b967cddfSBarry Smith case SSL_ERROR_NONE: 181d8dcb26dSBarry Smith if (request_len != (size_t)r) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Incomplete write to SSL socket"); 182b967cddfSBarry Smith break; 183b967cddfSBarry Smith default: 184b967cddfSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL socket write problem"); 185b967cddfSBarry Smith } 186b967cddfSBarry Smith 1875dc0f0a4SBarry Smith /* Now read the server's response, globus sends it in two chunks hence must read a second time if needed */ 1885dc0f0a4SBarry Smith ierr = PetscMemzero(buff,buffsize);CHKERRQ(ierr); 1895dc0f0a4SBarry Smith len = 0; 1905dc0f0a4SBarry Smith foundbody = PETSC_FALSE; 1915dc0f0a4SBarry Smith do { 1925dc0f0a4SBarry Smith char *clen; 1935dc0f0a4SBarry Smith int cl; 1945dc0f0a4SBarry Smith size_t nlen; 1955dc0f0a4SBarry Smith 1965dc0f0a4SBarry Smith r = SSL_read(ssl,buff+len,(int)buffsize); 1975dc0f0a4SBarry Smith len += r; 198b967cddfSBarry Smith switch (SSL_get_error(ssl,r)){ 199b967cddfSBarry Smith case SSL_ERROR_NONE: 200b967cddfSBarry Smith break; 201b967cddfSBarry Smith case SSL_ERROR_ZERO_RETURN: 2025dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 2035dc0f0a4SBarry Smith SSL_shutdown(ssl); 204b967cddfSBarry Smith break; 205b967cddfSBarry Smith case SSL_ERROR_SYSCALL: 2065dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 207b967cddfSBarry Smith break; 208b967cddfSBarry Smith default: 209b967cddfSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL read problem"); 210b967cddfSBarry Smith } 2115dc0f0a4SBarry Smith 2125dc0f0a4SBarry Smith ierr = PetscStrstr(buff,"Content-Length: ",&clen);CHKERRQ(ierr); 2135dc0f0a4SBarry Smith if (clen) { 2145dc0f0a4SBarry Smith clen += 15; 2155dc0f0a4SBarry Smith sscanf(clen,"%d",&cl); 2165dc0f0a4SBarry Smith if (!cl) foundbody = PETSC_TRUE; 2175dc0f0a4SBarry Smith else { 2185dc0f0a4SBarry Smith ierr = PetscStrstr(buff,"\r\n\r\n",&clen);CHKERRQ(ierr); 2195dc0f0a4SBarry Smith if (clen) { 2205dc0f0a4SBarry Smith ierr = PetscStrlen(clen,&nlen);CHKERRQ(ierr); 2215dc0f0a4SBarry Smith if (nlen-4 == (size_t) cl) foundbody = PETSC_TRUE; 2225dc0f0a4SBarry Smith } 2235dc0f0a4SBarry Smith } 2245dc0f0a4SBarry Smith } else { 2255dc0f0a4SBarry Smith /* if no content length than must leave because you don't know if you can read again */ 2265dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 2275dc0f0a4SBarry Smith } 2285dc0f0a4SBarry Smith } while (!foundbody); 229b967cddfSBarry Smith ierr = PetscInfo1(NULL,"HTTPS result follows: \n%s\n",buff);CHKERRQ(ierr); 230b967cddfSBarry Smith 231b967cddfSBarry Smith SSL_free(ssl); 232b967cddfSBarry Smith ierr = PetscFree(request);CHKERRQ(ierr); 233b967cddfSBarry Smith PetscFunctionReturn(0); 234b967cddfSBarry Smith } 235b967cddfSBarry Smith 236b967cddfSBarry Smith #undef __FUNCT__ 23704102261SBarry Smith #define __FUNCT__ "PetscHTTPRequest" 23804102261SBarry Smith /* 23904102261SBarry Smith PetscHTTPRequest - Send a request to an HTTP server 24004102261SBarry Smith 24104102261SBarry Smith Input Parameters: 24204102261SBarry Smith + type - either "POST" or "GET" 24304102261SBarry Smith . url - URL of request host/path 24404102261SBarry Smith . header - additional header information, may be NULL 24504102261SBarry Smith . ctype - data type of body, for example application/json 24604102261SBarry Smith . body - data to send to server 24704102261SBarry Smith . sock - obtained with PetscOpenSocket() 24804102261SBarry Smith - buffsize - size of buffer 24904102261SBarry Smith 25004102261SBarry Smith Output Parameter: 25104102261SBarry Smith . buff - everything returned from server 25204102261SBarry Smith */ 25304102261SBarry Smith PetscErrorCode PetscHTTPRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],int sock,char buff[],size_t buffsize) 25404102261SBarry Smith { 25504102261SBarry Smith char *request; 25604102261SBarry Smith size_t request_len; 25704102261SBarry Smith PetscErrorCode ierr; 25804102261SBarry Smith 25904102261SBarry Smith PetscFunctionBegin; 26004102261SBarry Smith ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr); 26104102261SBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 26204102261SBarry Smith 26304102261SBarry Smith ierr = PetscBinaryWrite(sock,request,request_len,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 26404102261SBarry Smith ierr = PetscFree(request);CHKERRQ(ierr); 26504102261SBarry Smith PetscBinaryRead(sock,buff,buffsize,PETSC_CHAR); 26604102261SBarry Smith buff[buffsize-1] = 0; 26704102261SBarry Smith ierr = PetscInfo1(NULL,"HTTP result follows: \n%s\n",buff);CHKERRQ(ierr); 26804102261SBarry Smith PetscFunctionReturn(0); 26904102261SBarry Smith } 27004102261SBarry Smith 27104102261SBarry Smith #undef __FUNCT__ 272b967cddfSBarry Smith #define __FUNCT__ "PetscHTTPSConnect" 273b967cddfSBarry Smith PetscErrorCode PetscHTTPSConnect(const char host[],int port,SSL_CTX *ctx,int *sock,SSL **ssl) 274b967cddfSBarry Smith { 275b967cddfSBarry Smith BIO *sbio; 276b967cddfSBarry Smith PetscErrorCode ierr; 277b967cddfSBarry Smith 278b967cddfSBarry Smith PetscFunctionBegin; 279b967cddfSBarry Smith /* Connect the TCP socket*/ 280b967cddfSBarry Smith ierr = PetscOpenSocket(host,port,sock);CHKERRQ(ierr); 281b967cddfSBarry Smith 282b967cddfSBarry Smith /* Connect the SSL socket */ 283b967cddfSBarry Smith *ssl = SSL_new(ctx); 284b967cddfSBarry Smith sbio = BIO_new_socket(*sock,BIO_NOCLOSE); 285b967cddfSBarry Smith SSL_set_bio(*ssl,sbio,sbio); 286b967cddfSBarry Smith if (SSL_connect(*ssl) <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL connect error"); 287b967cddfSBarry Smith PetscFunctionReturn(0); 288b967cddfSBarry Smith } 289b967cddfSBarry Smith 29068e69593SBarry Smith #undef __FUNCT__ 29168e69593SBarry Smith #define __FUNCT__ "PetscPullJSONValue" 29268e69593SBarry Smith /* 29368e69593SBarry Smith Given a JSON response containing the substring with "key" : "value" where there may or not be spaces around the : returns the value. 29468e69593SBarry Smith */ 29568e69593SBarry Smith PetscErrorCode PetscPullJSONValue(const char buff[],const char key[],char value[],size_t valuelen,PetscBool *found) 29668e69593SBarry Smith { 29768e69593SBarry Smith PetscErrorCode ierr; 29868e69593SBarry Smith char *v,*w; 29968e69593SBarry Smith char work[256]; 30068e69593SBarry Smith size_t len; 30168e69593SBarry Smith 30268e69593SBarry Smith PetscFunctionBegin; 30368e69593SBarry Smith ierr = PetscStrcpy(work,"\"");CHKERRQ(ierr); 30468e69593SBarry Smith ierr = PetscStrncat(work,key,250);CHKERRQ(ierr); 30568e69593SBarry Smith ierr = PetscStrcat(work,"\":");CHKERRQ(ierr); 30668e69593SBarry Smith ierr = PetscStrstr(buff,work,&v);CHKERRQ(ierr); 30768e69593SBarry Smith ierr = PetscStrlen(work,&len);CHKERRQ(ierr); 30868e69593SBarry Smith if (v) { 30968e69593SBarry Smith v += len; 31068e69593SBarry Smith } else { 31168e69593SBarry Smith work[len++-1] = 0; 31268e69593SBarry Smith ierr = PetscStrcat(work," :");CHKERRQ(ierr); 31368e69593SBarry Smith ierr = PetscStrstr(buff,work,&v);CHKERRQ(ierr); 31468e69593SBarry Smith if (!v) { 31568e69593SBarry Smith *found = PETSC_FALSE; 31668e69593SBarry Smith PetscFunctionReturn(0); 31768e69593SBarry Smith } 31868e69593SBarry Smith v += len; 31968e69593SBarry Smith } 32068e69593SBarry Smith ierr = PetscStrchr(v,'\"',&v);CHKERRQ(ierr); 32168e69593SBarry Smith if (!v) { 32268e69593SBarry Smith *found = PETSC_FALSE; 32368e69593SBarry Smith PetscFunctionReturn(0); 32468e69593SBarry Smith } 32568e69593SBarry Smith ierr = PetscStrchr(v+1,'\"',&w);CHKERRQ(ierr); 32668e69593SBarry Smith if (!w) { 32768e69593SBarry Smith *found = PETSC_FALSE; 32868e69593SBarry Smith PetscFunctionReturn(0); 32968e69593SBarry Smith } 33068e69593SBarry Smith *found = PETSC_TRUE; 331c1f4622dSBarry Smith ierr = PetscStrncpy(value,v+1,PetscMin((size_t)(w-v),valuelen));CHKERRQ(ierr); 33268e69593SBarry Smith PetscFunctionReturn(0); 33368e69593SBarry Smith } 3345dc0f0a4SBarry Smith 3355dc0f0a4SBarry Smith #include <ctype.h> 3365dc0f0a4SBarry Smith 3375dc0f0a4SBarry Smith #undef __FUNCT__ 3385dc0f0a4SBarry Smith #define __FUNCT__ "PetscPushJSONValue" 3395dc0f0a4SBarry Smith /* 3405dc0f0a4SBarry Smith Pushs a "key" : "value" pair onto a string 3415dc0f0a4SBarry Smith 3425dc0f0a4SBarry Smith Ignores lengths so can cause buffer overflow 3435dc0f0a4SBarry Smith */ 3445dc0f0a4SBarry Smith PetscErrorCode PetscPushJSONValue(char buff[],const char key[],const char value[],size_t bufflen) 3455dc0f0a4SBarry Smith { 3465dc0f0a4SBarry Smith PetscErrorCode ierr; 3475dc0f0a4SBarry Smith size_t len; 3485dc0f0a4SBarry Smith PetscBool special; 3495dc0f0a4SBarry Smith 3505dc0f0a4SBarry Smith PetscFunctionBegin; 3515dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"null",&special);CHKERRQ(ierr); 3525dc0f0a4SBarry Smith if (!special) { 3535dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"true",&special);CHKERRQ(ierr); 3545dc0f0a4SBarry Smith } 3555dc0f0a4SBarry Smith if (!special) { 3565dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"false",&special);CHKERRQ(ierr); 3575dc0f0a4SBarry Smith } 3585dc0f0a4SBarry Smith if (!special) { 3595dc0f0a4SBarry Smith PetscInt i; 3605dc0f0a4SBarry Smith 3615dc0f0a4SBarry Smith ierr = PetscStrlen(value,&len);CHKERRQ(ierr); 3625dc0f0a4SBarry Smith special = PETSC_TRUE; 3635dc0f0a4SBarry Smith for (i=0; i<(int)len; i++) { 3645dc0f0a4SBarry Smith if (!isdigit(value[i])) { 3655dc0f0a4SBarry Smith special = PETSC_FALSE; 3665dc0f0a4SBarry Smith break; 3675dc0f0a4SBarry Smith } 3685dc0f0a4SBarry Smith } 3695dc0f0a4SBarry Smith } 3705dc0f0a4SBarry Smith 3715dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 3725dc0f0a4SBarry Smith ierr = PetscStrcat(buff,key);CHKERRQ(ierr); 3735dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\":");CHKERRQ(ierr); 3745dc0f0a4SBarry Smith if (!special) { 3755dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 3765dc0f0a4SBarry Smith } 3775dc0f0a4SBarry Smith ierr = PetscStrcat(buff,value);CHKERRQ(ierr); 3785dc0f0a4SBarry Smith if (!special) { 3795dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 3805dc0f0a4SBarry Smith } 3815dc0f0a4SBarry Smith PetscFunctionReturn(0); 3825dc0f0a4SBarry Smith } 383